MEDIUM: make the trash be a chunk instead of a char *

The trash is used everywhere to store the results of temporary strings
built out of s(n)printf, or as a storage for a chunk when chunks are
needed.

Using global.tune.bufsize is not the most convenient thing either.

So let's replace trash with a chunk and directly use it as such. We can
then use trash.size as the natural way to get its size, and get rid of
many intermediary chunks that were previously used.

The patch is huge because it touches many areas but it makes the code
a lot more clear and even outlines places where trash was used without
being that obvious.
diff --git a/include/types/global.h b/include/types/global.h
index 3da65f5..28632b7 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -131,7 +131,7 @@
 extern int  actconn;            /* # of active sessions */
 extern int  listeners;
 extern int  jobs;               /* # of active jobs */
-extern char *trash;
+extern struct chunk trash;
 extern char *swap_buffer;
 extern int nb_oldpids;          /* contains the number of old pids found */
 extern const int zero;
diff --git a/src/acl.c b/src/acl.c
index 30a6d2d..adc89f3 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -1308,9 +1308,9 @@
 	opaque = 0;
 	pattern = NULL;
 	args[1] = "";
-	while (fgets(trash, global.tune.bufsize, file) != NULL) {
+	while (fgets(trash.str, trash.size, file) != NULL) {
 		line++;
-		c = trash;
+		c = trash.str;
 
 		/* ignore lines beginning with a dash */
 		if (*c == '#')
diff --git a/src/appsession.c b/src/appsession.c
index ec97336..a71f186 100644
--- a/src/appsession.c
+++ b/src/appsession.c
@@ -97,13 +97,9 @@
 				if (tick_is_expired(element->expire, now_ms)) {
 					if ((global.mode & MODE_DEBUG) &&
 					    (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
-						int len;
-						/*
-						  on Linux NULL pointers are caught by sprintf, on solaris -> segfault 
-						*/
-						len = sprintf(trash, "appsession_refresh: cleaning up expired Session '%s' on Server %s\n", 
-							      element->sessid, element->serverid?element->serverid:"(null)");
-						if (write(1, trash, len) < 0) /* shut gcc warning */;
+						chunk_printf(&trash, "appsession_refresh: cleaning up expired Session '%s' on Server %s\n", 
+						             element->sessid, element->serverid?element->serverid:"(null)");
+						if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
 					}
 					/* delete the expired element from within the hash table */
 					LIST_DEL(&element->hash_list);
diff --git a/src/cfgparse.c b/src/cfgparse.c
index ef3be08..d1f18f7 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -582,7 +582,7 @@
 		global.tune.bufsize = atol(args[1]);
 		if (global.tune.maxrewrite >= global.tune.bufsize / 2)
 			global.tune.maxrewrite = global.tune.bufsize / 2;
-		trash = realloc(trash, global.tune.bufsize);
+		chunk_init(&trash, realloc(trash.str, global.tune.bufsize), global.tune.bufsize);
 	}
 	else if (!strcmp(args[0], "tune.maxrewrite")) {
 		if (*(args[1]) == 0) {
@@ -1100,9 +1100,6 @@
 				if (kwl->kw[index].section != CFG_GLOBAL)
 					continue;
 				if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
-					/* prepare error message just in case */
-					snprintf(trash, global.tune.bufsize,
-						 "error near '%s' in '%s' section", args[0], "global");
 					rc = kwl->kw[index].parse(args, CFG_GLOBAL, NULL, NULL, file, linenum, &errmsg);
 					if (rc < 0) {
 						Alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
@@ -2928,9 +2925,9 @@
 			goto out;
 		}
 
-		expr = sample_parse_expr(args, &myidx, trash, global.tune.bufsize);
+		expr = sample_parse_expr(args, &myidx, trash.str, trash.size);
 		if (!expr) {
-			Alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], trash);
+			Alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], trash.str);
 			err_code |= ERR_ALERT | ERR_FATAL;
 			goto out;
 		}
@@ -5308,8 +5305,6 @@
 					continue;
 				if (strcmp(kwl->kw[index].kw, args[0]) == 0) {
 					/* prepare error message just in case */
-					snprintf(trash, global.tune.bufsize,
-						 "error near '%s' in %s section", args[0], cursection);
 					rc = kwl->kw[index].parse(args, CFG_LISTEN, curproxy, &defproxy, file, linenum, &errmsg);
 					if (rc < 0) {
 						Alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
@@ -6607,10 +6602,8 @@
 			/* enable separate counters */
 			if (curproxy->options2 & PR_O2_SOCKSTAT) {
 				listener->counters = (struct licounters *)calloc(1, sizeof(struct licounters));
-				if (!listener->name) {
-					sprintf(trash, "sock-%d", listener->luid);
-					listener->name = strdup(trash);
-				}
+				if (!listener->name)
+					memprintf(&listener->name, "sock-%d", listener->luid);
 			}
 
 			if (curproxy->options & PR_O_TCP_NOLING)
diff --git a/src/checks.c b/src/checks.c
index 8e49549..e3c8620 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -198,10 +198,8 @@
  * Show information in logs about failed health check if server is UP
  * or succeeded health checks if server is DOWN.
  */
-static void set_server_check_status(struct server *s, short status, char *desc) {
-
-	struct chunk msg;
-
+static void set_server_check_status(struct server *s, short status, char *desc)
+{
 	if (status == HCHK_STATUS_START) {
 		s->result = SRV_CHK_UNKNOWN;	/* no result yet */
 		s->check.desc[0] = '\0';
@@ -238,7 +236,7 @@
 
 		int health, rise, fall, state;
 
-		chunk_init(&msg, trash, global.tune.bufsize);
+		chunk_reset(&trash);
 
 		/* FIXME begin: calculate local version of the health/rise/fall/state */
 		health = s->health;
@@ -274,22 +272,22 @@
 		}
 		/* FIXME end: calculate local version of the health/rise/fall/state */
 
-		chunk_appendf(&msg,
-			"Health check for %sserver %s/%s %s%s",
-			s->state & SRV_BACKUP ? "backup " : "",
-			s->proxy->id, s->id,
-			(s->result & SRV_CHK_DISABLE)?"conditionally ":"",
-			(s->result & SRV_CHK_RUNNING)?"succeeded":"failed");
+		chunk_appendf(&trash,
+		             "Health check for %sserver %s/%s %s%s",
+		             s->state & SRV_BACKUP ? "backup " : "",
+		             s->proxy->id, s->id,
+		             (s->result & SRV_CHK_DISABLE)?"conditionally ":"",
+		             (s->result & SRV_CHK_RUNNING)?"succeeded":"failed");
 
-		server_status_printf(&msg, s, SSP_O_HCHK, -1);
+		server_status_printf(&trash, s, SSP_O_HCHK, -1);
 
-		chunk_appendf(&msg, ", status: %d/%d %s",
-			(state & SRV_RUNNING) ? (health - rise + 1) : (health),
-			(state & SRV_RUNNING) ? (fall) : (rise),
-			(state & SRV_RUNNING)?"UP":"DOWN");
+		chunk_appendf(&trash, ", status: %d/%d %s",
+		             (state & SRV_RUNNING) ? (health - rise + 1) : (health),
+		             (state & SRV_RUNNING) ? (fall) : (rise),
+		             (state & SRV_RUNNING)?"UP":"DOWN");
 
-		Warning("%s.\n", trash);
-		send_log(s->proxy, LOG_NOTICE, "%s.\n", trash);
+		Warning("%s.\n", trash.str);
+		send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
 	}
 }
 
@@ -393,7 +391,6 @@
 void set_server_down(struct server *s)
 {
 	struct server *srv;
-	struct chunk msg;
 	int xferred;
 
 	if (s->state & SRV_MAINTAIN) {
@@ -418,28 +415,28 @@
 		 */
 		xferred = redistribute_pending(s);
 
-		chunk_init(&msg, trash, global.tune.bufsize);
+		chunk_reset(&trash);
 
 		if (s->state & SRV_MAINTAIN) {
-			chunk_appendf(&msg,
-				"%sServer %s/%s is DOWN for maintenance", s->state & SRV_BACKUP ? "Backup " : "",
-				s->proxy->id, s->id);
+			chunk_appendf(&trash,
+			             "%sServer %s/%s is DOWN for maintenance", s->state & SRV_BACKUP ? "Backup " : "",
+			             s->proxy->id, s->id);
 		} else {
-			chunk_appendf(&msg,
-				"%sServer %s/%s is DOWN", s->state & SRV_BACKUP ? "Backup " : "",
-				s->proxy->id, s->id);
+			chunk_appendf(&trash,
+			             "%sServer %s/%s is DOWN", s->state & SRV_BACKUP ? "Backup " : "",
+			             s->proxy->id, s->id);
 
-			server_status_printf(&msg, s,
-						((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS))?SSP_O_HCHK:0),
-						xferred);
+			server_status_printf(&trash, s,
+			                     ((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? SSP_O_HCHK : 0),
+			                     xferred);
 		}
-		Warning("%s.\n", trash);
+		Warning("%s.\n", trash.str);
 
 		/* we don't send an alert if the server was previously paused */
 		if (srv_was_paused)
-			send_log(s->proxy, LOG_NOTICE, "%s.\n", trash);
+			send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
 		else
-			send_log(s->proxy, LOG_ALERT, "%s.\n", trash);
+			send_log(s->proxy, LOG_ALERT, "%s.\n", trash.str);
 
 		if (prev_srv_count && s->proxy->srv_bck == 0 && s->proxy->srv_act == 0)
 			set_backend_down(s->proxy);
@@ -459,7 +456,6 @@
 void set_server_up(struct server *s) {
 
 	struct server *srv;
-	struct chunk msg;
 	int xferred;
 	unsigned int old_state = s->state;
 
@@ -510,24 +506,24 @@
 		 */
 		xferred = check_for_pending(s);
 
-		chunk_init(&msg, trash, global.tune.bufsize);
+		chunk_reset(&trash);
 
 		if (old_state & SRV_MAINTAIN) {
-			chunk_appendf(&msg,
-				"%sServer %s/%s is UP (leaving maintenance)", s->state & SRV_BACKUP ? "Backup " : "",
-				s->proxy->id, s->id);
+			chunk_appendf(&trash,
+			             "%sServer %s/%s is UP (leaving maintenance)", s->state & SRV_BACKUP ? "Backup " : "",
+			             s->proxy->id, s->id);
 		} else {
-			chunk_appendf(&msg,
-				"%sServer %s/%s is UP", s->state & SRV_BACKUP ? "Backup " : "",
-				s->proxy->id, s->id);
+			chunk_appendf(&trash,
+			             "%sServer %s/%s is UP", s->state & SRV_BACKUP ? "Backup " : "",
+			             s->proxy->id, s->id);
 
-			server_status_printf(&msg, s,
-						((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS))?SSP_O_HCHK:0),
-						xferred);
+			server_status_printf(&trash, s,
+			                     ((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? SSP_O_HCHK : 0),
+			                     xferred);
 		}
 
-		Warning("%s.\n", trash);
-		send_log(s->proxy, LOG_NOTICE, "%s.\n", trash);
+		Warning("%s.\n", trash.str);
+		send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
 
 		if (s->state & SRV_CHECKED)
 			for(srv = s->tracknext; srv; srv = srv->tracknext)
@@ -544,7 +540,6 @@
 static void set_server_disabled(struct server *s) {
 
 	struct server *srv;
-	struct chunk msg;
 	int xferred;
 
 	s->state |= SRV_GOINGDOWN;
@@ -557,19 +552,19 @@
 	 */
 	xferred = redistribute_pending(s);
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
-	chunk_appendf(&msg,
-		"Load-balancing on %sServer %s/%s is disabled",
-		s->state & SRV_BACKUP ? "Backup " : "",
-		s->proxy->id, s->id);
+	chunk_appendf(&trash,
+	             "Load-balancing on %sServer %s/%s is disabled",
+	             s->state & SRV_BACKUP ? "Backup " : "",
+	             s->proxy->id, s->id);
 
-	server_status_printf(&msg, s,
-				((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS))?SSP_O_HCHK:0),
-				xferred);
+	server_status_printf(&trash, s,
+	                     ((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? SSP_O_HCHK : 0),
+	                     xferred);
 
-	Warning("%s.\n", trash);
-	send_log(s->proxy, LOG_NOTICE, "%s.\n", trash);
+	Warning("%s.\n", trash.str);
+	send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
 
 	if (!s->proxy->srv_bck && !s->proxy->srv_act)
 		set_backend_down(s->proxy);
@@ -582,7 +577,6 @@
 static void set_server_enabled(struct server *s) {
 
 	struct server *srv;
-	struct chunk msg;
 	int xferred;
 
 	s->state &= ~SRV_GOINGDOWN;
@@ -594,27 +588,27 @@
 	 */
 	xferred = check_for_pending(s);
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
-	chunk_appendf(&msg,
-		"Load-balancing on %sServer %s/%s is enabled again",
-		s->state & SRV_BACKUP ? "Backup " : "",
-		s->proxy->id, s->id);
+	chunk_appendf(&trash,
+	             "Load-balancing on %sServer %s/%s is enabled again",
+	             s->state & SRV_BACKUP ? "Backup " : "",
+	             s->proxy->id, s->id);
 
-	server_status_printf(&msg, s,
-				((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS))?SSP_O_HCHK:0),
-				xferred);
+	server_status_printf(&trash, s,
+	                     ((!s->track && !(s->proxy->options2 & PR_O2_LOGHCHKS)) ? SSP_O_HCHK : 0),
+	                     xferred);
 
-	Warning("%s.\n", trash);
-	send_log(s->proxy, LOG_NOTICE, "%s.\n", trash);
+	Warning("%s.\n", trash.str);
+	send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
 
 	if (s->state & SRV_CHECKED)
 		for(srv = s->tracknext; srv; srv = srv->tracknext)
 			set_server_enabled(srv);
 }
 
-void health_adjust(struct server *s, short status) {
-
+void health_adjust(struct server *s, short status)
+{
 	int failed;
 	int expire;
 
@@ -652,8 +646,8 @@
 	if (s->consecutive_errors < s->consecutive_errors_limit)
 		return;
 
-	sprintf(trash, "Detected %d consecutive errors, last one was: %s",
-		s->consecutive_errors, get_analyze_status(status));
+	chunk_printf(&trash, "Detected %d consecutive errors, last one was: %s",
+	             s->consecutive_errors, get_analyze_status(status));
 
 	switch (s->onerror) {
 		case HANA_ONERR_FASTINTER:
@@ -669,7 +663,7 @@
 
 		case HANA_ONERR_FAILCHK:
 		/* simulate a failed health check */
-			set_server_check_status(s, HCHK_STATUS_HANA, trash);
+			set_server_check_status(s, HCHK_STATUS_HANA, trash.str);
 
 			if (s->health > s->rise) {
 				s->health--; /* still good */
@@ -683,7 +677,7 @@
 		case HANA_ONERR_MARKDWN:
 		/* mark server down */
 			s->health = s->rise;
-			set_server_check_status(s, HCHK_STATUS_HANA, trash);
+			set_server_check_status(s, HCHK_STATUS_HANA, trash.str);
 			set_server_down(s);
 
 			break;
@@ -1298,7 +1292,7 @@
 			}
 			else if ((s->proxy->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK) {
 				if (s->proxy->options2 & PR_O2_CHK_SNDST)
-					bo_putblk(s->check.bo, trash, httpchk_build_status_header(s, trash));
+					bo_putblk(s->check.bo, trash.str, httpchk_build_status_header(s, trash.str));
 				bo_putstr(s->check.bo, "\r\n");
 				*s->check.bo->p = '\0'; /* to make gdb output easier to read */
 			}
diff --git a/src/connection.c b/src/connection.c
index 9ccebbc..d698e69 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -282,15 +282,14 @@
 int conn_recv_proxy(struct connection *conn, int flag)
 {
 	char *line, *end;
-	int len;
 
 	/* we might have been called just after an asynchronous shutr */
 	if (conn->flags & CO_FL_SOCK_RD_SH)
 		goto fail;
 
 	do {
-		len = recv(conn->t.sock.fd, trash, global.tune.bufsize, MSG_PEEK);
-		if (len < 0) {
+		trash.len = recv(conn->t.sock.fd, trash.str, trash.size, MSG_PEEK);
+		if (trash.len < 0) {
 			if (errno == EINTR)
 				continue;
 			if (errno == EAGAIN) {
@@ -301,18 +300,18 @@
 		}
 	} while (0);
 
-	if (len < 6)
+	if (trash.len < 6)
 		goto missing;
 
-	line = trash;
-	end = trash + len;
+	line = trash.str;
+	end = trash.str + trash.len;
 
 	/* Decode a possible proxy request, fail early if it does not match */
 	if (strncmp(line, "PROXY ", 6) != 0)
 		goto fail;
 
 	line += 6;
-	if (len < 18) /* shortest possible line */
+	if (trash.len < 18) /* shortest possible line */
 		goto missing;
 
 	if (!memcmp(line, "TCP4 ", 5) != 0) {
@@ -425,12 +424,12 @@
 	 * exact line at once. If we don't get the exact same result, we
 	 * fail.
 	 */
-	len = line - trash;
+	trash.len = line - trash.str;
 	do {
-		int len2 = recv(conn->t.sock.fd, trash, len, 0);
+		int len2 = recv(conn->t.sock.fd, trash.str, trash.len, 0);
 		if (len2 < 0 && errno == EINTR)
 			continue;
-		if (len2 != len)
+		if (len2 != trash.len)
 			goto fail;
 	} while (0);
 
@@ -542,7 +541,7 @@
  */
 int conn_local_send_proxy(struct connection *conn, unsigned int flag)
 {
-	int ret, len;
+	int ret;
 
 	/* we might have been called just after an asynchronous shutw */
 	if (conn->flags & CO_FL_SOCK_WR_SH)
@@ -557,14 +556,14 @@
 	if (!(conn->flags & CO_FL_ADDR_TO_SET))
 		goto out_error;
 
-	len = make_proxy_line(trash, global.tune.bufsize, &conn->addr.from, &conn->addr.to);
-	if (!len)
+	trash.len = make_proxy_line(trash.str, trash.size, &conn->addr.from, &conn->addr.to);
+	if (!trash.len)
 		goto out_error;
 
-	/* we have to send trash from len bytes. If the data layer has a
+	/* we have to send the whole trash. If the data layer has a
 	 * pending write, we'll also set MSG_MORE.
 	 */
-	ret = send(conn->t.sock.fd, trash, len, (conn->flags & CO_FL_DATA_WR_ENA) ? MSG_MORE : 0);
+	ret = send(conn->t.sock.fd, trash.str, trash.len, (conn->flags & CO_FL_DATA_WR_ENA) ? MSG_MORE : 0);
 
 	if (ret == 0)
 		goto out_wait;
@@ -575,7 +574,7 @@
 		goto out_error;
 	}
 
-	if (ret != len)
+	if (ret != trash.len)
 		goto out_error;
 
 	/* The connection is ready now, simply return and let the connection
diff --git a/src/dumpstats.c b/src/dumpstats.c
index cdf0bbb..eefce58 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -525,7 +525,6 @@
 	struct stksess *ts;
 	uint32_t uint32_key;
 	unsigned char ip6_key[sizeof(struct in6_addr)];
-	struct chunk msg;
 	long long value;
 	int data_type;
 	void *ptr;
@@ -599,10 +598,10 @@
 	case STAT_CLI_O_TAB:
 		if (!ts)
 			return;
-		chunk_init(&msg, trash, global.tune.bufsize);
-		if (!stats_dump_table_head_to_buffer(&msg, si, px, px))
+		chunk_reset(&trash);
+		if (!stats_dump_table_head_to_buffer(&trash, si, px, px))
 			return;
-		stats_dump_table_entry_to_buffer(&msg, si, px, ts);
+		stats_dump_table_entry_to_buffer(&trash, si, px, ts);
 		return;
 
 	case STAT_CLI_O_CLR:
@@ -1026,8 +1025,8 @@
 			}
 
 			/* return server's effective weight at the moment */
-			snprintf(trash, global.tune.bufsize, "%d (initial %d)\n", sv->uweight, sv->iweight);
-			bi_putstr(si->ib, trash);
+			snprintf(trash.str, trash.size, "%d (initial %d)\n", sv->uweight, sv->iweight);
+			bi_putstr(si->ib, trash.str);
 			return 1;
 		}
 		else { /* not "get weight" */
@@ -1495,7 +1494,7 @@
 			if (buffer_almost_full(si->ib->buf))
 				break;
 
-			reql = bo_getline(si->ob, trash, global.tune.bufsize);
+			reql = bo_getline(si->ob, trash.str, trash.size);
 			if (reql <= 0) { /* closed or EOL not found */
 				if (reql == 0)
 					break;
@@ -1507,8 +1506,8 @@
 			 * replace it with an LF and skip only this part.
 			 */
 			for (len = 0; len < reql; len++)
-				if (trash[len] == ';') {
-					trash[len] = '\n';
+				if (trash.str[len] == ';') {
+					trash.str[len] = '\n';
 					reql = len + 1;
 					break;
 				}
@@ -1518,26 +1517,26 @@
 			 * line.
 			 */
 			len = reql - 1;
-			if (trash[len] != '\n') {
+			if (trash.str[len] != '\n') {
 				si->applet.st0 = STAT_CLI_END;
 				continue;
 			}
 
-			if (len && trash[len-1] == '\r')
+			if (len && trash.str[len-1] == '\r')
 				len--;
 
-			trash[len] = '\0';
+			trash.str[len] = '\0';
 
 			si->applet.st0 = STAT_CLI_PROMPT;
 			if (len) {
-				if (strcmp(trash, "quit") == 0) {
+				if (strcmp(trash.str, "quit") == 0) {
 					si->applet.st0 = STAT_CLI_END;
 					continue;
 				}
-				else if (strcmp(trash, "prompt") == 0)
+				else if (strcmp(trash.str, "prompt") == 0)
 					si->applet.st1 = !si->applet.st1;
-				else if (strcmp(trash, "help") == 0 ||
-					 !stats_sock_parse_request(si, trash)) {
+				else if (strcmp(trash.str, "help") == 0 ||
+					 !stats_sock_parse_request(si, trash.str)) {
 					si->applet.ctx.cli.msg = stats_sock_usage_msg;
 					si->applet.st0 = STAT_CLI_PRINT;
 				}
@@ -1665,10 +1664,9 @@
 static int stats_dump_raw_to_buffer(struct stream_interface *si)
 {
 	struct proxy *px;
-	struct chunk msg;
 	unsigned int up;
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
 	switch (si->conn->xprt_st) {
 	case STAT_ST_INIT:
@@ -1678,8 +1676,8 @@
 
 	case STAT_ST_HEAD:
 		if (si->applet.ctx.stats.flags & STAT_SHOW_STAT) {
-			print_csv_header(&msg);
-			if (bi_putchk(si->ib, &msg) == -1)
+			print_csv_header(&trash);
+			if (bi_putchk(si->ib, &trash) == -1)
 				return 0;
 		}
 
@@ -1689,7 +1687,7 @@
 	case STAT_ST_INFO:
 		up = (now.tv_sec - start_date.tv_sec);
 		if (si->applet.ctx.stats.flags & STAT_SHOW_INFO) {
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     "Name: " PRODUCT_NAME "\n"
 				     "Version: " HAPROXY_VERSION "\n"
 				     "Release_date: " HAPROXY_DATE "\n"
@@ -1729,7 +1727,7 @@
 				     nb_tasks_cur, run_queue_cur, idle_pct,
 				     global.node, global.desc?global.desc:""
 				     );
-			if (bi_putchk(si->ib, &msg) == -1)
+			if (bi_putchk(si->ib, &trash) == -1)
 				return 0;
 		}
 
@@ -1782,13 +1780,12 @@
 static int stats_http_redir(struct stream_interface *si, struct uri_auth *uri)
 {
 	struct session *s = si->conn->xprt_ctx;
-	struct chunk msg;
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
 	switch (si->conn->xprt_st) {
 	case STAT_ST_INIT:
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			"HTTP/1.0 303 See Other\r\n"
 			"Cache-Control: no-cache\r\n"
 			"Content-Type: text/plain\r\n"
@@ -1800,9 +1797,9 @@
 			 stat_status_codes[si->applet.ctx.stats.st_code]) ?
 				stat_status_codes[si->applet.ctx.stats.st_code] :
 				stat_status_codes[STAT_STATUS_UNKN]);
-		chunk_appendf(&msg, "\r\n\r\n");
+		chunk_appendf(&trash, "\r\n\r\n");
 
-		if (bi_putchk(si->ib, &msg) == -1)
+		if (bi_putchk(si->ib, &trash) == -1)
 			return 0;
 
 		s->txn.status = 303;
@@ -1885,14 +1882,13 @@
 	struct session *s = si->conn->xprt_ctx;
 	struct channel *rep = si->ib;
 	struct proxy *px;
-	struct chunk msg;
 	unsigned int up;
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
 	switch (si->conn->xprt_st) {
 	case STAT_ST_INIT:
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "HTTP/1.0 200 OK\r\n"
 			     "Cache-Control: no-cache\r\n"
 			     "Connection: close\r\n"
@@ -1900,13 +1896,13 @@
 			     (si->applet.ctx.stats.flags & STAT_FMT_CSV) ? "text/plain" : "text/html");
 
 		if (uri->refresh > 0 && !(si->applet.ctx.stats.flags & STAT_NO_REFRESH))
-			chunk_appendf(&msg, "Refresh: %d\r\n",
+			chunk_appendf(&trash, "Refresh: %d\r\n",
 				     uri->refresh);
 
-		chunk_appendf(&msg, "\r\n");
+		chunk_appendf(&trash, "\r\n");
 
 		s->txn.status = 200;
-		if (bi_putchk(rep, &msg) == -1)
+		if (bi_putchk(rep, &trash) == -1)
 			return 0;
 
 		if (!(s->flags & SN_ERR_MASK))  // this is not really an error but it is
@@ -1926,7 +1922,7 @@
 	case STAT_ST_HEAD:
 		if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
 			/* WARNING! This must fit in the first buffer !!! */
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 			     "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n"
 			     "\"http://www.w3.org/TR/html4/loose.dtd\">\n"
 			     "<html><head><title>Statistics Report for " PRODUCT_NAME "%s%s</title>\n"
@@ -2019,9 +2015,9 @@
 			     (uri->flags&ST_SHNODE) ? (uri->node ? uri->node : global.node) : ""
 			     );
 		} else {
-			print_csv_header(&msg);
+			print_csv_header(&trash);
 		}
-		if (bi_putchk(rep, &msg) == -1)
+		if (bi_putchk(rep, &trash) == -1)
 			return 0;
 
 		si->conn->xprt_st = STAT_ST_INFO;
@@ -2035,7 +2031,7 @@
 			 * become tricky if we want to support 4kB buffers !
 			 */
 		if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 			     "<body><h1><a href=\"" PRODUCT_URL "\" style=\"text-decoration: none;\">"
 			     PRODUCT_NAME "%s</a></h1>\n"
 			     "<h2>Statistics Report for pid %d%s%s%s%s</h2>\n"
@@ -2084,13 +2080,13 @@
 			     );
 
 			if (si->applet.ctx.stats.flags & STAT_HIDE_DOWN)
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     "<li><a href=\"%s%s%s\">Show all servers</a><br>\n",
 				     uri->uri_prefix,
 				     "",
 				     (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "");
 			else
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     "<li><a href=\"%s%s%s\">Hide 'DOWN' servers</a><br>\n",
 				     uri->uri_prefix,
 				     ";up",
@@ -2098,31 +2094,31 @@
 
 			if (uri->refresh > 0) {
 				if (si->applet.ctx.stats.flags & STAT_NO_REFRESH)
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     "<li><a href=\"%s%s%s\">Enable refresh</a><br>\n",
 					     uri->uri_prefix,
 					     (si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
 					     "");
 				else
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     "<li><a href=\"%s%s%s\">Disable refresh</a><br>\n",
 					     uri->uri_prefix,
 					     (si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
 					     ";norefresh");
 			}
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 			     "<li><a href=\"%s%s%s\">Refresh now</a><br>\n",
 			     uri->uri_prefix,
 			     (si->applet.ctx.stats.flags & STAT_HIDE_DOWN) ? ";up" : "",
 			     (si->applet.ctx.stats.flags & STAT_NO_REFRESH) ? ";norefresh" : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 			     "<li><a href=\"%s;csv%s\">CSV export</a><br>\n",
 			     uri->uri_prefix,
 			     (uri->refresh > 0) ? ";norefresh" : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 			     "</ul></td>"
 			     "<td align=\"left\" valign=\"top\" nowrap width=\"1%%\">"
 			     "<b>External resources:</b><ul style=\"margin-top: 0.25em;\">\n"
@@ -2138,21 +2134,21 @@
 			if (si->applet.ctx.stats.st_code) {
 				switch (si->applet.ctx.stats.st_code) {
 				case STAT_STATUS_DONE:
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<p><div class=active3>"
 						     "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
 						     "Action processed successfully."
 						     "</div>\n", uri->uri_prefix);
 					break;
 				case STAT_STATUS_NONE:
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<p><div class=active2>"
 						     "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
 						     "Nothing has changed."
 						     "</div>\n", uri->uri_prefix);
 					break;
 				case STAT_STATUS_PART:
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<p><div class=active2>"
 						     "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
 						     "Action partially processed.<br>"
@@ -2160,7 +2156,7 @@
 						     "</div>\n", uri->uri_prefix);
 					break;
 				case STAT_STATUS_ERRP:
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<p><div class=active0>"
 						     "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
 						     "Action not processed because of invalid parameters."
@@ -2172,7 +2168,7 @@
 						     "</div>\n", uri->uri_prefix);
 					break;
 				case STAT_STATUS_EXCD:
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<p><div class=active0>"
 						     "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
 						     "<b>Action not processed : the buffer couldn't store all the data.<br>"
@@ -2180,23 +2176,23 @@
 						     "</div>\n", uri->uri_prefix);
 					break;
 				case STAT_STATUS_DENY:
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<p><div class=active0>"
 						     "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
 						     "<b>Action denied.</b>"
 						     "</div>\n", uri->uri_prefix);
 					break;
 				default:
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<p><div class=active6>"
 						     "<a class=lfsb href=\"%s\" title=\"Remove this message\">[X]</a> "
 						     "Unexpected result."
 						     "</div>\n", uri->uri_prefix);
 				}
-				chunk_appendf(&msg,"<p>\n");
+				chunk_appendf(&trash,"<p>\n");
 			}
 
-			if (bi_putchk(rep, &msg) == -1)
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		}
 
@@ -2226,8 +2222,8 @@
 
 	case STAT_ST_END:
 		if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
-			chunk_appendf(&msg, "</body></html>\n");
-			if (bi_putchk(rep, &msg) == -1)
+			chunk_appendf(&trash, "</body></html>\n");
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		}
 
@@ -2256,9 +2252,8 @@
 	struct channel *rep = si->ib;
 	struct server *sv, *svs;	/* server and server-state, server-state=server or server->track */
 	struct listener *l;
-	struct chunk msg;
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
 	switch (si->applet.ctx.stats.px_st) {
 	case STAT_PX_ST_INIT:
@@ -2299,27 +2294,27 @@
 		if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
 			if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
 				/* A form to enable/disable this proxy servers */
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 					"<form action=\"%s\" method=\"post\">",
 					uri->uri_prefix);
 			}
 
 			/* print a new table */
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     "<table class=\"tbl\" width=\"100%%\">\n"
 				     "<tr class=\"titre\">"
 				     "<th class=\"pxname\" width=\"10%%\"");
 
 			if (uri->flags&ST_SHLGNDS) {
 				/* cap, mode, id */
-				chunk_appendf(&msg, " title=\"cap: %s, mode: %s, id: %d",
+				chunk_appendf(&trash, " title=\"cap: %s, mode: %s, id: %d",
 					proxy_cap_str(px->cap), proxy_mode_str(px->mode),
 					px->uuid);
 
-				chunk_appendf(&msg, "\"");
+				chunk_appendf(&trash, "\"");
 			}
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     ">%s<a name=\"%s\"></a>"
 				     "<a class=px href=\"#%s\">%s</a>%s</th>"
 				     "<th class=\"%s\" width=\"90%%\">%s</th>"
@@ -2334,10 +2329,10 @@
 
 			if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
 				 /* Column heading for Enable or Disable server */
-				chunk_appendf(&msg, "<th rowspan=2 width=1></th>");
+				chunk_appendf(&trash, "<th rowspan=2 width=1></th>");
 			}
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     "<th rowspan=2></th>"
 				     "<th colspan=3>Queue</th>"
 				     "<th colspan=3>Session rate</th><th colspan=5>Sessions</th>"
@@ -2356,7 +2351,7 @@
 				     "<th>Thrtle</th>\n"
 				     "</tr>");
 
-			if (bi_putchk(rep, &msg) == -1)
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		}
 
@@ -2368,16 +2363,16 @@
 		if ((px->cap & PR_CAP_FE) &&
 		    (!(si->applet.ctx.stats.flags & STAT_BOUND) || (si->applet.ctx.stats.type & (1 << STATS_TYPE_FE)))) {
 			if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* name, queue */
 				     "<tr class=\"frontend\">");
 
 				if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
 					/* Column sub-heading for Enable or Disable server */
-					chunk_appendf(&msg, "<td></td>");
+					chunk_appendf(&trash, "<td></td>");
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     "<td class=ac>"
 				     "<a name=\"%s/Frontend\"></a>"
 				     "<a class=lfsb href=\"#%s/Frontend\">Frontend</a></td>"
@@ -2386,7 +2381,7 @@
 				     px->id, px->id);
 
 				if (px->mode == PR_MODE_HTTP) {
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     /* sessions rate : current, max, limit */
 						     "<td title=\"Cur: %u req/s\"><u>%s</u></td><td title=\"Max: %u req/s\"><u>%s</u></td><td>%s</td>"
 						     "",
@@ -2396,7 +2391,7 @@
 						     U2H1(px->fe_counters.sps_max),
 						     LIM2A2(px->fe_sps_lim, "-"));
 				} else {
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     /* sessions rate : current, max, limit */
 						     "<td>%s</td><td>%s</td><td>%s</td>"
 						     "",
@@ -2404,7 +2399,7 @@
 						     U2H1(px->fe_counters.sps_max), LIM2A2(px->fe_sps_lim, "-"));
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* sessions: current, max, limit */
 				     "<td>%s</td><td>%s</td><td>%s</td>"
 				     "<td"
@@ -2415,16 +2410,16 @@
 				if (px->mode == PR_MODE_HTTP) {
 					int i;
 
-					chunk_appendf(&msg, " title=\"%lld requests:", px->fe_counters.p.http.cum_req);
+					chunk_appendf(&trash, " title=\"%lld requests:", px->fe_counters.p.http.cum_req);
 
 					for (i = 1; i < 6; i++)
-						chunk_appendf(&msg, " %dxx=%lld,", i, px->fe_counters.p.http.rsp[i]);
+						chunk_appendf(&trash, " %dxx=%lld,", i, px->fe_counters.p.http.rsp[i]);
 
-					chunk_appendf(&msg, " other=%lld,", px->fe_counters.p.http.rsp[0]);
-					chunk_appendf(&msg, " intercepted=%lld\"", px->fe_counters.intercepted_req);
+					chunk_appendf(&trash, " other=%lld,", px->fe_counters.p.http.rsp[0]);
+					chunk_appendf(&trash, " intercepted=%lld\"", px->fe_counters.intercepted_req);
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* sessions: total, lbtot */
 				     ">%s%s%s</td><td></td>"
 				     /* bytes : in, out */
@@ -2435,7 +2430,7 @@
 				     (px->mode == PR_MODE_HTTP)?"</u>":"",
 				     U2H7(px->fe_counters.bytes_in), U2H8(px->fe_counters.bytes_out));
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* denied: req, resp */
 				     "<td>%s</td><td>%s</td>"
 				     /* errors : request, connect, response */
@@ -2452,7 +2447,7 @@
 				     px->state == PR_STREADY ? "OPEN" :
 				     px->state == PR_STFULL ? "FULL" : "STOP");
 			} else {
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* pxid, name, queue cur, queue max, */
 				     "%s,FRONTEND,,,"
 				     /* sessions : current, max, limit, total */
@@ -2491,29 +2486,29 @@
 					int i;
 
 					for (i=1; i<6; i++)
-						chunk_appendf(&msg, "%lld,", px->fe_counters.p.http.rsp[i]);
+						chunk_appendf(&trash, "%lld,", px->fe_counters.p.http.rsp[i]);
 
-					chunk_appendf(&msg, "%lld,", px->fe_counters.p.http.rsp[0]);
+					chunk_appendf(&trash, "%lld,", px->fe_counters.p.http.rsp[0]);
 				} else {
-					chunk_appendf(&msg, ",,,,,,");
+					chunk_appendf(&trash, ",,,,,,");
 				}
 
 				/* failed health analyses */
-				chunk_appendf(&msg, ",");
+				chunk_appendf(&trash, ",");
 
 				/* requests : req_rate, req_rate_max, req_tot, */
-				chunk_appendf(&msg, "%u,%u,%lld,",
+				chunk_appendf(&trash, "%u,%u,%lld,",
 					     read_freq_ctr(&px->fe_req_per_sec),
 					     px->fe_counters.p.http.rps_max, px->fe_counters.p.http.cum_req);
 
 				/* errors: cli_aborts, srv_aborts */
-				chunk_appendf(&msg, ",,");
+				chunk_appendf(&trash, ",,");
 
 				/* finish with EOL */
-				chunk_appendf(&msg, "\n");
+				chunk_appendf(&trash, "\n");
 			}
 
-			if (bi_putchk(rep, &msg) == -1)
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		}
 
@@ -2540,40 +2535,40 @@
 			}
 
 			if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
-				chunk_appendf(&msg, "<tr class=socket>");
+				chunk_appendf(&trash, "<tr class=socket>");
 				if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
 					 /* Column sub-heading for Enable or Disable server */
-					chunk_appendf(&msg, "<td></td>");
+					chunk_appendf(&trash, "<td></td>");
 				}
-				chunk_appendf(&msg, "<td class=ac");
+				chunk_appendf(&trash, "<td class=ac");
 
 					if (uri->flags&ST_SHLGNDS) {
 						char str[INET6_ADDRSTRLEN];
 						int port;
 
-						chunk_appendf(&msg, " title=\"");
+						chunk_appendf(&trash, " title=\"");
 
 						port = get_host_port(&l->addr);
 						switch (addr_to_str(&l->addr, str, sizeof(str))) {
 						case AF_INET:
-							chunk_appendf(&msg, "IPv4: %s:%d, ", str, port);
+							chunk_appendf(&trash, "IPv4: %s:%d, ", str, port);
 							break;
 						case AF_INET6:
-							chunk_appendf(&msg, "IPv6: [%s]:%d, ", str, port);
+							chunk_appendf(&trash, "IPv6: [%s]:%d, ", str, port);
 							break;
 						case AF_UNIX:
-							chunk_appendf(&msg, "unix, ");
+							chunk_appendf(&trash, "unix, ");
 							break;
 						case -1:
-							chunk_appendf(&msg, "(%s), ", strerror(errno));
+							chunk_appendf(&trash, "(%s), ", strerror(errno));
 							break;
 						}
 
 						/* id */
-						chunk_appendf(&msg, "id: %d\"", l->luid);
+						chunk_appendf(&trash, "id: %d\"", l->luid);
 					}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* name, queue */
 				     ">%s<a name=\"%s/+%s\"></a>"
 				     "<a class=lfsb href=\"#%s/+%s\">%s</a></td><td colspan=3>%s</td>"
@@ -2591,7 +2586,7 @@
 				     U2H3(l->nbconn), U2H4(l->counters->conn_max), U2H5(l->maxconn),
 				     U2H6(l->counters->cum_conn), U2H7(l->counters->bytes_in), U2H8(l->counters->bytes_out));
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* denied: req, resp */
 				     "<td>%s</td><td>%s</td>"
 				     /* errors: request, connect, response */
@@ -2607,7 +2602,7 @@
 				     U2H2(l->counters->failed_req),
 				     (l->nbconn < l->maxconn) ? (l->state == LI_LIMITED) ? "WAITING" : "OPEN" : "FULL");
 			} else {
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* pxid, name, queue cur, queue max, */
 				     "%s,%s,,,"
 				     /* sessions: current, max, limit, total */
@@ -2649,7 +2644,7 @@
 				     relative_pid, px->uuid, l->luid, STATS_TYPE_SO);
 			}
 
-			if (bi_putchk(rep, &msg) == -1)
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		}
 
@@ -2710,67 +2705,67 @@
 							       "NOLB %d/%d &darr;", "NOLB",
 							       "<i>no check</i>" };
 				if ((sv->state & SRV_MAINTAIN) || (svs->state & SRV_MAINTAIN)) {
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					    /* name */
 					    "<tr class=\"maintain\">"
 					);
 				}
 				else {
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					    /* name */
 					    "<tr class=\"%s%d\">",
 					    (sv->state & SRV_BACKUP) ? "backup" : "active", sv_state);
 				}
 
 				if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						"<td><input type=\"checkbox\" name=\"s\" value=\"%s\"></td>",
 						sv->id);
 				}
 
-				chunk_appendf(&msg, "<td class=ac");
+				chunk_appendf(&trash, "<td class=ac");
 
 				if (uri->flags&ST_SHLGNDS) {
 					char str[INET6_ADDRSTRLEN];
 
-					chunk_appendf(&msg, " title=\"");
+					chunk_appendf(&trash, " title=\"");
 
 					switch (addr_to_str(&sv->addr, str, sizeof(str))) {
 					case AF_INET:
-						chunk_appendf(&msg, "IPv4: %s:%d, ", str, get_host_port(&sv->addr));
+						chunk_appendf(&trash, "IPv4: %s:%d, ", str, get_host_port(&sv->addr));
 						break;
 					case AF_INET6:
-						chunk_appendf(&msg, "IPv6: [%s]:%d, ", str, get_host_port(&sv->addr));
+						chunk_appendf(&trash, "IPv6: [%s]:%d, ", str, get_host_port(&sv->addr));
 						break;
 					case AF_UNIX:
-						chunk_appendf(&msg, "unix, ");
+						chunk_appendf(&trash, "unix, ");
 						break;
 					case -1:
-						chunk_appendf(&msg, "(%s), ", strerror(errno));
+						chunk_appendf(&trash, "(%s), ", strerror(errno));
 						break;
 					default: /* address family not supported */
 						break;
 					}
 
 					/* id */
-					chunk_appendf(&msg, "id: %d", sv->puid);
+					chunk_appendf(&trash, "id: %d", sv->puid);
 
 					/* cookie */
 					if (sv->cookie) {
 						struct chunk src;
 
-						chunk_appendf(&msg, ", cookie: '");
+						chunk_appendf(&trash, ", cookie: '");
 
 						chunk_initlen(&src, sv->cookie, 0, strlen(sv->cookie));
-						chunk_htmlencode(&msg, &src);
+						chunk_htmlencode(&trash, &src);
 
-						chunk_appendf(&msg, "'");
+						chunk_appendf(&trash, "'");
 					}
 
-					chunk_appendf(&msg, "\"");
+					chunk_appendf(&trash, "\"");
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     ">%s<a name=\"%s/%s\"></a>"
 				     "<a class=lfsb href=\"#%s/%s\">%s</a>%s</td>"
 				     /* queue : current, max, limit */
@@ -2792,15 +2787,15 @@
 				if (px->mode == PR_MODE_HTTP) {
 					int i;
 
-					chunk_appendf(&msg, " title=\"rsp codes:");
+					chunk_appendf(&trash, " title=\"rsp codes:");
 
 					for (i = 1; i < 6; i++)
-						chunk_appendf(&msg, " %dxx=%lld,", i, sv->counters.p.http.rsp[i]);
+						chunk_appendf(&trash, " %dxx=%lld,", i, sv->counters.p.http.rsp[i]);
 
-					chunk_appendf(&msg, " other=%lld\"", sv->counters.p.http.rsp[0]);
+					chunk_appendf(&trash, " other=%lld\"", sv->counters.p.http.rsp[0]);
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* sessions: total, lbtot */
 				     ">%s%s%s</td><td>%s</td>",
 				     (px->mode == PR_MODE_HTTP)?"<u>":"",
@@ -2808,7 +2803,7 @@
 				     (px->mode == PR_MODE_HTTP)?"</u>":"",
 				     U2H1(sv->counters.cum_lbconn));
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* bytes : in, out */
 				     "<td>%s</td><td>%s</td>"
 				     /* denied: req, resp */
@@ -2829,54 +2824,54 @@
 				     sv->counters.retries, sv->counters.redispatches);
 
 				/* status, lest check */
-				chunk_appendf(&msg, "<td class=ac>");
+				chunk_appendf(&trash, "<td class=ac>");
 
 				if (sv->state & SRV_MAINTAIN) {
-					chunk_appendf(&msg, "%s ",
+					chunk_appendf(&trash, "%s ",
 						human_time(now.tv_sec - sv->last_change, 1));
-					chunk_appendf(&msg, "MAINT");
+					chunk_appendf(&trash, "MAINT");
 				}
 				else if (svs != sv && svs->state & SRV_MAINTAIN) {
-					chunk_appendf(&msg, "%s ",
+					chunk_appendf(&trash, "%s ",
 						human_time(now.tv_sec - svs->last_change, 1));
-					chunk_appendf(&msg, "MAINT(via)");
+					chunk_appendf(&trash, "MAINT(via)");
 				}
 				else if (svs->state & SRV_CHECKED) {
-					chunk_appendf(&msg, "%s ",
+					chunk_appendf(&trash, "%s ",
 						human_time(now.tv_sec - svs->last_change, 1));
 
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     srv_hlt_st[sv_state],
 					     (svs->state & SRV_RUNNING) ? (svs->health - svs->rise + 1) : (svs->health),
 					     (svs->state & SRV_RUNNING) ? (svs->fall) : (svs->rise));
 				}
 
 				if (sv->state & SRV_CHECKED) {
-					chunk_appendf(&msg, "</td><td class=ac title=\"%s",
+					chunk_appendf(&trash, "</td><td class=ac title=\"%s",
 						get_check_status_description(sv->check.status));
 
 					if (*sv->check.desc) {
 						struct chunk src;
 
-						chunk_appendf(&msg, ": ");
+						chunk_appendf(&trash, ": ");
 
 						chunk_initlen(&src, sv->check.desc, 0, strlen(sv->check.desc));
-						chunk_htmlencode(&msg, &src);
+						chunk_htmlencode(&trash, &src);
 					}
 
-					chunk_appendf(&msg, "\"><u> %s%s",
+					chunk_appendf(&trash, "\"><u> %s%s",
 						tv_iszero(&sv->check.start)?"":"* ",
 						get_check_status_info(sv->check.status));
 
 					if (sv->check.status >= HCHK_STATUS_L57DATA)
-						chunk_appendf(&msg, "/%d", sv->check.code);
+						chunk_appendf(&trash, "/%d", sv->check.code);
 
 					if (sv->check.status >= HCHK_STATUS_CHECKED && sv->check.duration >= 0)
-					chunk_appendf(&msg, " in %lums</u>", sv->check.duration);
+					chunk_appendf(&trash, " in %lums</u>", sv->check.duration);
 				} else
-					chunk_appendf(&msg, "</td><td>");
+					chunk_appendf(&trash, "</td><td>");
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* weight */
 				     "</td><td class=ac>%d</td>"
 				     /* act, bck */
@@ -2888,23 +2883,23 @@
 
 				/* check failures: unique, fatal, down time */
 				if (sv->state & SRV_CHECKED) {
-					chunk_appendf(&msg, "<td title=\"Failed Health Checks%s\"><u>%lld",
+					chunk_appendf(&trash, "<td title=\"Failed Health Checks%s\"><u>%lld",
 					     svs->observe?"/Health Analyses":"", svs->counters.failed_checks);
 
 					if (svs->observe)
-						chunk_appendf(&msg, "/%lld", svs->counters.failed_hana);
+						chunk_appendf(&trash, "/%lld", svs->counters.failed_hana);
 
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     "</u></td>"
 					     "<td>%lld</td><td>%s</td>"
 					     "",
 					     svs->counters.down_trans, human_time(srv_downtime(sv), 1));
 				} else if (sv != svs)
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     "<td class=ac colspan=3><a class=lfsb href=\"#%s/%s\">via %s/%s<a></td>",
 							svs->proxy->id, svs->id, svs->proxy->id, svs->id);
 				else
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     "<td colspan=3></td>");
 
 				/* throttle */
@@ -2913,10 +2908,10 @@
 				    now.tv_sec >= sv->last_change) {
 					unsigned int ratio;
 					ratio = MAX(1, 100 * (now.tv_sec - sv->last_change) / sv->slowstart);
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<td class=ac>%d %%</td></tr>\n", ratio);
 				} else {
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 						     "<td class=ac>-</td></tr>\n");
 				}
 			} else {
@@ -2924,7 +2919,7 @@
 							       "UP %d/%d,", "UP,",
 							       "NOLB %d/%d,", "NOLB,",
 							       "no check," };
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* pxid, name */
 				     "%s,%s,"
 				     /* queue : current, max */
@@ -2950,19 +2945,19 @@
 
 				/* status */
 				if (sv->state & SRV_MAINTAIN) {
-					chunk_appendf(&msg, "MAINT,");
+					chunk_appendf(&trash, "MAINT,");
 				}
 				else if (svs != sv && svs->state & SRV_MAINTAIN) {
-					chunk_appendf(&msg, "MAINT(via),");
+					chunk_appendf(&trash, "MAINT(via),");
 				}
 				else {
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					    srv_hlt_st[sv_state],
 					    (svs->state & SRV_RUNNING) ? (svs->health - svs->rise + 1) : (svs->health),
 					    (svs->state & SRV_RUNNING) ? (svs->fall) : (svs->rise));
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* weight, active, backup */
 				     "%d,%d,%d,"
 				     "",
@@ -2972,16 +2967,16 @@
 
 				/* check failures: unique, fatal; last change, total downtime */
 				if (sv->state & SRV_CHECKED)
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     "%lld,%lld,%d,%d,",
 					     sv->counters.failed_checks, sv->counters.down_trans,
 					     (int)(now.tv_sec - sv->last_change), srv_downtime(sv));
 				else
-					chunk_appendf(&msg,
+					chunk_appendf(&trash,
 					     ",,,,");
 
 				/* queue limit, pid, iid, sid, */
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     "%s,"
 				     "%d,%d,%d,",
 				     LIM2A0(sv->maxqueue, ""),
@@ -2993,45 +2988,45 @@
 				    now.tv_sec >= sv->last_change) {
 					unsigned int ratio;
 					ratio = MAX(1, 100 * (now.tv_sec - sv->last_change) / sv->slowstart);
-					chunk_appendf(&msg, "%d", ratio);
+					chunk_appendf(&trash, "%d", ratio);
 				}
 
 				/* sessions: lbtot */
-				chunk_appendf(&msg, ",%lld,", sv->counters.cum_lbconn);
+				chunk_appendf(&trash, ",%lld,", sv->counters.cum_lbconn);
 
 				/* tracked */
 				if (sv->track)
-					chunk_appendf(&msg, "%s/%s,",
+					chunk_appendf(&trash, "%s/%s,",
 						sv->track->proxy->id, sv->track->id);
 				else
-					chunk_appendf(&msg, ",");
+					chunk_appendf(&trash, ",");
 
 				/* type */
-				chunk_appendf(&msg, "%d,", STATS_TYPE_SV);
+				chunk_appendf(&trash, "%d,", STATS_TYPE_SV);
 
 				/* rate */
-				chunk_appendf(&msg, "%u,,%u,",
+				chunk_appendf(&trash, "%u,,%u,",
 					     read_freq_ctr(&sv->sess_per_sec),
 					     sv->counters.sps_max);
 
 				if (sv->state & SRV_CHECKED) {
 					/* check_status */
-					chunk_appendf(&msg, "%s,", get_check_status_info(sv->check.status));
+					chunk_appendf(&trash, "%s,", get_check_status_info(sv->check.status));
 
 					/* check_code */
 					if (sv->check.status >= HCHK_STATUS_L57DATA)
-						chunk_appendf(&msg, "%u,", sv->check.code);
+						chunk_appendf(&trash, "%u,", sv->check.code);
 					else
-						chunk_appendf(&msg, ",");
+						chunk_appendf(&trash, ",");
 
 					/* check_duration */
 					if (sv->check.status >= HCHK_STATUS_CHECKED)
-						chunk_appendf(&msg, "%lu,", sv->check.duration);
+						chunk_appendf(&trash, "%lu,", sv->check.duration);
 					else
-						chunk_appendf(&msg, ",");
+						chunk_appendf(&trash, ",");
 
 				} else {
-					chunk_appendf(&msg, ",,,");
+					chunk_appendf(&trash, ",,,");
 				}
 
 				/* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */
@@ -3039,27 +3034,27 @@
 					int i;
 
 					for (i=1; i<6; i++)
-						chunk_appendf(&msg, "%lld,", sv->counters.p.http.rsp[i]);
+						chunk_appendf(&trash, "%lld,", sv->counters.p.http.rsp[i]);
 
-					chunk_appendf(&msg, "%lld,", sv->counters.p.http.rsp[0]);
+					chunk_appendf(&trash, "%lld,", sv->counters.p.http.rsp[0]);
 				} else {
-					chunk_appendf(&msg, ",,,,,,");
+					chunk_appendf(&trash, ",,,,,,");
 				}
 
 				/* failed health analyses */
-				chunk_appendf(&msg, "%lld,",  sv->counters.failed_hana);
+				chunk_appendf(&trash, "%lld,",  sv->counters.failed_hana);
 
 				/* requests : req_rate, req_rate_max, req_tot, */
-				chunk_appendf(&msg, ",,,");
+				chunk_appendf(&trash, ",,,");
 
 				/* errors: cli_aborts, srv_aborts */
-				chunk_appendf(&msg, "%lld,%lld,",
+				chunk_appendf(&trash, "%lld,%lld,",
 					     sv->counters.cli_aborts, sv->counters.srv_aborts);
 
 				/* finish with EOL */
-				chunk_appendf(&msg, "\n");
+				chunk_appendf(&trash, "\n");
 			}
-			if (bi_putchk(rep, &msg) == -1)
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		} /* for sv */
 
@@ -3071,35 +3066,35 @@
 		if ((px->cap & PR_CAP_BE) &&
 		    (!(si->applet.ctx.stats.flags & STAT_BOUND) || (si->applet.ctx.stats.type & (1 << STATS_TYPE_BE)))) {
 			if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
-				chunk_appendf(&msg, "<tr class=\"backend\">");
+				chunk_appendf(&trash, "<tr class=\"backend\">");
 				if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
 					/* Column sub-heading for Enable or Disable server */
-					chunk_appendf(&msg, "<td></td>");
+					chunk_appendf(&trash, "<td></td>");
 				}
-				chunk_appendf(&msg, "<td class=ac");
+				chunk_appendf(&trash, "<td class=ac");
 
 				if (uri->flags&ST_SHLGNDS) {
 					/* balancing */
-					 chunk_appendf(&msg, " title=\"balancing: %s",
+					 chunk_appendf(&trash, " title=\"balancing: %s",
 						 backend_lb_algo_str(px->lbprm.algo & BE_LB_ALGO));
 
 					/* cookie */
 					if (px->cookie_name) {
 						struct chunk src;
 
-						chunk_appendf(&msg, ", cookie: '");
+						chunk_appendf(&trash, ", cookie: '");
 
 						chunk_initlen(&src, px->cookie_name, 0, strlen(px->cookie_name));
-						chunk_htmlencode(&msg, &src);
+						chunk_htmlencode(&trash, &src);
 
-						chunk_appendf(&msg, "'");
+						chunk_appendf(&trash, "'");
 					}
 
-					chunk_appendf(&msg, "\"");
+					chunk_appendf(&trash, "\"");
 
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* name */
 				     ">%s<a name=\"%s/Backend\"></a>"
 				     "<a class=lfsb href=\"#%s/Backend\">Backend</a>%s</td>"
@@ -3114,7 +3109,7 @@
 				     U2H0(px->nbpend) /* or px->totpend ? */, U2H1(px->be_counters.nbpend_max),
 				     U2H2(read_freq_ctr(&px->be_sess_per_sec)), U2H3(px->be_counters.sps_max));
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* sessions: current, max, limit */
 				     "<td>%s</td><td>%s</td><td>%s</td>"
 				     "<td"
@@ -3125,15 +3120,15 @@
 				if (px->mode == PR_MODE_HTTP) {
 					int i;
 
-					chunk_appendf(&msg, " title=\"rsp codes:");
+					chunk_appendf(&trash, " title=\"rsp codes:");
 
 					for (i = 1; i < 6; i++)
-						chunk_appendf(&msg, " %dxx=%lld", i, px->be_counters.p.http.rsp[i]);
+						chunk_appendf(&trash, " %dxx=%lld", i, px->be_counters.p.http.rsp[i]);
 
-					chunk_appendf(&msg, " other=%lld\"", px->be_counters.p.http.rsp[0]);
+					chunk_appendf(&trash, " other=%lld\"", px->be_counters.p.http.rsp[0]);
 				}
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* sessions: total, lbtot */
 				     ">%s%s%s</td><td>%s</td>"
 				     /* bytes: in, out */
@@ -3145,7 +3140,7 @@
 				     U2H7(px->be_counters.cum_lbconn),
 				     U2H8(px->be_counters.bytes_in), U2H9(px->be_counters.bytes_out));
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* denied: req, resp */
 				     "<td>%s</td><td>%s</td>"
 				     /* errors : request, connect */
@@ -3173,7 +3168,7 @@
 				     (px->lbprm.tot_weight * px->lbprm.wmult + px->lbprm.wdiv - 1) / px->lbprm.wdiv,
 				     px->srv_act, px->srv_bck);
 
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* rest of backend: nothing, down transitions, total downtime, throttle */
 				     "<td class=ac>&nbsp;</td><td>%d</td>"
 				     "<td>%s</td>"
@@ -3182,7 +3177,7 @@
 				     px->down_trans,
 				     px->srv?human_time(be_downtime(px), 1):"&nbsp;");
 			} else {
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 				     /* pxid, name */
 				     "%s,BACKEND,"
 				     /* queue : current, max */
@@ -3233,28 +3228,28 @@
 					int i;
 
 					for (i=1; i<6; i++)
-						chunk_appendf(&msg, "%lld,", px->be_counters.p.http.rsp[i]);
+						chunk_appendf(&trash, "%lld,", px->be_counters.p.http.rsp[i]);
 
-					chunk_appendf(&msg, "%lld,", px->be_counters.p.http.rsp[0]);
+					chunk_appendf(&trash, "%lld,", px->be_counters.p.http.rsp[0]);
 				} else {
-					chunk_appendf(&msg, ",,,,,,");
+					chunk_appendf(&trash, ",,,,,,");
 				}
 
 				/* failed health analyses */
-				chunk_appendf(&msg, ",");
+				chunk_appendf(&trash, ",");
 
 				/* requests : req_rate, req_rate_max, req_tot, */
-				chunk_appendf(&msg, ",,,");
+				chunk_appendf(&trash, ",,,");
 
 				/* errors: cli_aborts, srv_aborts */
-				chunk_appendf(&msg, "%lld,%lld,",
+				chunk_appendf(&trash, "%lld,%lld,",
 					     px->be_counters.cli_aborts, px->be_counters.srv_aborts);
 
 				/* finish with EOL */
-				chunk_appendf(&msg, "\n");
+				chunk_appendf(&trash, "\n");
 
 			}
-			if (bi_putchk(rep, &msg) == -1)
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		}
 
@@ -3263,11 +3258,11 @@
 
 	case STAT_PX_ST_END:
 		if (!(si->applet.ctx.stats.flags & STAT_FMT_CSV)) {
-			chunk_appendf(&msg, "</table>");
+			chunk_appendf(&trash, "</table>");
 
 			if (px->cap & PR_CAP_BE && px->srv && (si->applet.ctx.stats.flags & STAT_ADMIN)) {
 				/* close the form used to enable/disable this proxy servers */
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 					"Choose the action to perform on the checked servers : "
 					"<select name=action>"
 					"<option value=\"\"></option>"
@@ -3283,9 +3278,9 @@
 					px->uuid);
 			}
 
-			chunk_appendf(&msg, "<p>\n");
+			chunk_appendf(&trash, "<p>\n");
 
-			if (bi_putchk(rep, &msg) == -1)
+			if (bi_putchk(rep, &trash) == -1)
 				return 0;
 		}
 
@@ -3310,18 +3305,17 @@
 static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
 {
 	struct tm tm;
-	struct chunk msg;
 	struct session *sess;
 	extern const char *monthname[12];
 	char pn[INET6_ADDRSTRLEN];
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 	sess = si->applet.ctx.sess.target;
 
 	if (si->applet.ctx.sess.section > 0 && si->applet.ctx.sess.uid != sess->uniq_id) {
 		/* session changed, no need to go any further */
-		chunk_appendf(&msg, "  *** session terminated while we were watching it ***\n");
-		if (bi_putchk(si->ib, &msg) == -1)
+		chunk_appendf(&trash, "  *** session terminated while we were watching it ***\n");
+		if (bi_putchk(si->ib, &trash) == -1)
 			return 0;
 		si->applet.ctx.sess.target = NULL;
 		si->applet.ctx.sess.uid = 0;
@@ -3335,7 +3329,7 @@
 		/* fall through */
 
 	case 1:
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "%p: id=%u, proto=%s",
 			     sess,
 			     sess->uniq_id,
@@ -3344,23 +3338,23 @@
 		switch (addr_to_str(&sess->si[0].conn->addr.from, pn, sizeof(pn))) {
 		case AF_INET:
 		case AF_INET6:
-			chunk_appendf(&msg, " source=%s:%d\n",
+			chunk_appendf(&trash, " source=%s:%d\n",
 				     pn, get_host_port(&sess->si[0].conn->addr.from));
 			break;
 		case AF_UNIX:
-			chunk_appendf(&msg, " source=unix:%d\n", sess->listener->luid);
+			chunk_appendf(&trash, " source=unix:%d\n", sess->listener->luid);
 			break;
 		default:
 			/* no more information to print right now */
-			chunk_appendf(&msg, "\n");
+			chunk_appendf(&trash, "\n");
 			break;
 		}
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  flags=0x%x, conn_retries=%d, srv_conn=%p, pend_pos=%p\n",
 			     sess->flags, sess->si[1].conn_retries, sess->srv_conn, sess->pend_pos);
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  frontend=%s (id=%u mode=%s), listener=%s (id=%u)",
 			     sess->fe->id, sess->fe->uuid, sess->fe->mode ? "http" : "tcp",
 			     sess->listener ? sess->listener->name ? sess->listener->name : "?" : "?",
@@ -3370,67 +3364,67 @@
 		switch (addr_to_str(&sess->si[0].conn->addr.to, pn, sizeof(pn))) {
 		case AF_INET:
 		case AF_INET6:
-			chunk_appendf(&msg, " addr=%s:%d\n",
+			chunk_appendf(&trash, " addr=%s:%d\n",
 				     pn, get_host_port(&sess->si[0].conn->addr.to));
 			break;
 		case AF_UNIX:
-			chunk_appendf(&msg, " addr=unix:%d\n", sess->listener->luid);
+			chunk_appendf(&trash, " addr=unix:%d\n", sess->listener->luid);
 			break;
 		default:
 			/* no more information to print right now */
-			chunk_appendf(&msg, "\n");
+			chunk_appendf(&trash, "\n");
 			break;
 		}
 
 		if (sess->be->cap & PR_CAP_BE)
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     "  backend=%s (id=%u mode=%s)",
 				     sess->be->id,
 				     sess->be->uuid, sess->be->mode ? "http" : "tcp");
 		else
-			chunk_appendf(&msg, "  backend=<NONE> (id=-1 mode=-)");
+			chunk_appendf(&trash, "  backend=<NONE> (id=-1 mode=-)");
 
 		conn_get_from_addr(sess->si[1].conn);
 		switch (addr_to_str(&sess->si[1].conn->addr.from, pn, sizeof(pn))) {
 		case AF_INET:
 		case AF_INET6:
-			chunk_appendf(&msg, " addr=%s:%d\n",
+			chunk_appendf(&trash, " addr=%s:%d\n",
 				     pn, get_host_port(&sess->si[1].conn->addr.from));
 			break;
 		case AF_UNIX:
-			chunk_appendf(&msg, " addr=unix\n");
+			chunk_appendf(&trash, " addr=unix\n");
 			break;
 		default:
 			/* no more information to print right now */
-			chunk_appendf(&msg, "\n");
+			chunk_appendf(&trash, "\n");
 			break;
 		}
 
 		if (sess->be->cap & PR_CAP_BE)
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     "  server=%s (id=%u)",
 				     target_srv(&sess->target) ? target_srv(&sess->target)->id : "<none>",
 				     target_srv(&sess->target) ? target_srv(&sess->target)->puid : 0);
 		else
-			chunk_appendf(&msg, "  server=<NONE> (id=-1)");
+			chunk_appendf(&trash, "  server=<NONE> (id=-1)");
 
 		conn_get_to_addr(sess->si[1].conn);
 		switch (addr_to_str(&sess->si[1].conn->addr.to, pn, sizeof(pn))) {
 		case AF_INET:
 		case AF_INET6:
-			chunk_appendf(&msg, " addr=%s:%d\n",
+			chunk_appendf(&trash, " addr=%s:%d\n",
 				     pn, get_host_port(&sess->si[1].conn->addr.to));
 			break;
 		case AF_UNIX:
-			chunk_appendf(&msg, " addr=unix\n");
+			chunk_appendf(&trash, " addr=unix\n");
 			break;
 		default:
 			/* no more information to print right now */
-			chunk_appendf(&msg, "\n");
+			chunk_appendf(&trash, "\n");
 			break;
 		}
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  task=%p (state=0x%02x nice=%d calls=%d exp=%s%s)\n",
 			     sess->task,
 			     sess->task->state,
@@ -3442,13 +3436,13 @@
 			     task_in_rq(sess->task) ? ", running" : "");
 
 		get_localtime(sess->logs.accept_date.tv_sec, &tm);
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  task created [%02d/%s/%04d:%02d:%02d:%02d.%06d] (age=%s)\n",
 			     tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
 			     tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(sess->logs.accept_date.tv_usec),
 			     human_time(now.tv_sec - sess->logs.accept_date.tv_sec, 1));
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  si[0]=%p (state=%d flags=0x%02x fd=%d exp=%s, et=0x%03x)\n",
 			     &sess->si[0],
 			     sess->si[0].state,
@@ -3460,7 +3454,7 @@
 			                     TICKS_TO_MS(1000)) : "<NEVER>",
 			     sess->si[0].err_type);
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  si[1]=%p (state=%d flags=0x%02x fd=%d exp=%s, et=0x%03x)\n",
 			     &sess->si[1],
 			     sess->si[1].state,
@@ -3472,13 +3466,13 @@
 			                     TICKS_TO_MS(1000)) : "<NEVER>",
 			     sess->si[1].err_type);
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  txn=%p (flags=0x%x meth=%d status=%d req.st=%d rsp.st=%d)\n",
 			     &sess->txn, sess->txn.flags, sess->txn.meth, sess->txn.status,
 			     sess->txn.req.msg_state, sess->txn.rsp.msg_state);
 
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  req=%p (f=0x%06x an=0x%x i=%d o=%d pipe=%d fwd=%d)\n"
 			     "      an_exp=%s",
 			     sess->req,
@@ -3490,13 +3484,13 @@
 			     human_time(TICKS_TO_MS(sess->req->analyse_exp - now_ms),
 					TICKS_TO_MS(1000)) : "<NEVER>");
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     " rex=%s",
 			     sess->req->rex ?
 			     human_time(TICKS_TO_MS(sess->req->rex - now_ms),
 					TICKS_TO_MS(1000)) : "<NEVER>");
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     " wex=%s\n"
 			     "      data=%p p=%d next=%d total=%lld\n",
 			     sess->req->wex ?
@@ -3507,7 +3501,7 @@
 			     sess->txn.req.next,
 			     sess->req->total);
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     "  res=%p (f=0x%06x an=0x%x i=%d o=%d pipe=%d fwd=%d)\n"
 			     "      an_exp=%s",
 			     sess->rep,
@@ -3519,13 +3513,13 @@
 			     human_time(TICKS_TO_MS(sess->rep->analyse_exp - now_ms),
 					TICKS_TO_MS(1000)) : "<NEVER>");
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     " rex=%s",
 			     sess->rep->rex ?
 			     human_time(TICKS_TO_MS(sess->rep->rex - now_ms),
 					TICKS_TO_MS(1000)) : "<NEVER>");
 
-		chunk_appendf(&msg,
+		chunk_appendf(&trash,
 			     " wex=%s\n"
 			     "      data=%p p=%d next=%d total=%lld\n",
 			     sess->rep->wex ?
@@ -3536,7 +3530,7 @@
 			     sess->txn.rsp.next,
 			     sess->rep->total);
 
-		if (bi_putchk(si->ib, &msg) == -1)
+		if (bi_putchk(si->ib, &trash) == -1)
 			return 0;
 
 		/* use other states to dump the contents */
@@ -3554,8 +3548,6 @@
  */
 static int stats_dump_sess_to_buffer(struct stream_interface *si)
 {
-	struct chunk msg;
-
 	if (unlikely(si->ib->flags & (CF_WRITE_ERROR|CF_SHUTW))) {
 		/* If we're forced to shut down, we might have to remove our
 		 * reference to the last session being dumped.
@@ -3569,7 +3561,7 @@
 		return 1;
 	}
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
 	switch (si->conn->xprt_st) {
 	case STAT_ST_INIT:
@@ -3615,7 +3607,7 @@
 				break;
 			}
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     "%p: proto=%s",
 				     curr_sess,
 				     curr_sess->listener->proto->name);
@@ -3624,7 +3616,7 @@
 			switch (addr_to_str(&curr_sess->si[0].conn->addr.from, pn, sizeof(pn))) {
 			case AF_INET:
 			case AF_INET6:
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 					     " src=%s:%d fe=%s be=%s srv=%s",
 					     pn,
 					     get_host_port(&curr_sess->si[0].conn->addr.from),
@@ -3634,7 +3626,7 @@
 					     );
 				break;
 			case AF_UNIX:
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 					     " src=unix:%d fe=%s be=%s srv=%s",
 					     curr_sess->listener->luid,
 					     curr_sess->fe->id,
@@ -3644,13 +3636,13 @@
 				break;
 			}
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     " ts=%02x age=%s calls=%d",
 				     curr_sess->task->state,
 				     human_time(now.tv_sec - curr_sess->logs.tv_accept.tv_sec, 1),
 				     curr_sess->task->calls);
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     " rq[f=%06xh,i=%d,an=%02xh,rx=%s",
 				     curr_sess->req->flags,
 				     curr_sess->req->buf->i,
@@ -3659,19 +3651,19 @@
 				     human_time(TICKS_TO_MS(curr_sess->req->rex - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     ",wx=%s",
 				     curr_sess->req->wex ?
 				     human_time(TICKS_TO_MS(curr_sess->req->wex - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     ",ax=%s]",
 				     curr_sess->req->analyse_exp ?
 				     human_time(TICKS_TO_MS(curr_sess->req->analyse_exp - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     " rp[f=%06xh,i=%d,an=%02xh,rx=%s",
 				     curr_sess->rep->flags,
 				     curr_sess->rep->buf->i,
@@ -3680,19 +3672,19 @@
 				     human_time(TICKS_TO_MS(curr_sess->rep->rex - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     ",wx=%s",
 				     curr_sess->rep->wex ?
 				     human_time(TICKS_TO_MS(curr_sess->rep->wex - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     ",ax=%s]",
 				     curr_sess->rep->analyse_exp ?
 				     human_time(TICKS_TO_MS(curr_sess->rep->analyse_exp - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     " s0=[%d,%1xh,fd=%d,ex=%s]",
 				     curr_sess->si[0].state,
 				     curr_sess->si[0].flags,
@@ -3701,7 +3693,7 @@
 				     human_time(TICKS_TO_MS(curr_sess->si[0].exp - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     " s1=[%d,%1xh,fd=%d,ex=%s]",
 				     curr_sess->si[1].state,
 				     curr_sess->si[1].flags,
@@ -3710,17 +3702,17 @@
 				     human_time(TICKS_TO_MS(curr_sess->si[1].exp - now_ms),
 						TICKS_TO_MS(1000)) : "");
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     " exp=%s",
 				     curr_sess->task->expire ?
 				     human_time(TICKS_TO_MS(curr_sess->task->expire - now_ms),
 						TICKS_TO_MS(1000)) : "");
 			if (task_in_rq(curr_sess->task))
-				chunk_appendf(&msg, " run(nice=%d)", curr_sess->task->nice);
+				chunk_appendf(&trash, " run(nice=%d)", curr_sess->task->nice);
 
-			chunk_appendf(&msg, "\n");
+			chunk_appendf(&trash, "\n");
 
-			if (bi_putchk(si->ib, &msg) == -1) {
+			if (bi_putchk(si->ib, &trash) == -1) {
 				/* let's try again later from this session. We add ourselves into
 				 * this session's users so that it can remove us upon termination.
 				 */
@@ -3735,11 +3727,11 @@
 		if (si->applet.ctx.sess.target) {
 			/* specified session not found */
 			if (si->applet.ctx.sess.section > 0)
-				chunk_appendf(&msg, "  *** session terminated while we were watching it ***\n");
+				chunk_appendf(&trash, "  *** session terminated while we were watching it ***\n");
 			else
-				chunk_appendf(&msg, "Session not found.\n");
+				chunk_appendf(&trash, "Session not found.\n");
 
-			if (bi_putchk(si->ib, &msg) == -1)
+			if (bi_putchk(si->ib, &trash) == -1)
 				return 0;
 
 			si->applet.ctx.sess.target = NULL;
@@ -3764,7 +3756,6 @@
 static int stats_table_request(struct stream_interface *si, bool show)
 {
 	struct session *s = si->conn->xprt_ctx;
-	struct chunk msg;
 	struct ebmb_node *eb;
 	int dt;
 	bool skip_entry;
@@ -3790,7 +3781,7 @@
 		return 1;
 	}
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
 	while (si->conn->xprt_st != STAT_ST_FIN) {
 		switch (si->conn->xprt_st) {
@@ -3812,7 +3803,7 @@
 			}
 
 			if (si->applet.ctx.table.proxy->table.size) {
-				if (show && !stats_dump_table_head_to_buffer(&msg, si, si->applet.ctx.table.proxy,
+				if (show && !stats_dump_table_head_to_buffer(&trash, si, si->applet.ctx.table.proxy,
 									     si->applet.ctx.table.target))
 					return 0;
 
@@ -3878,7 +3869,7 @@
 			}
 
 			if (show && !skip_entry &&
-			    !stats_dump_table_entry_to_buffer(&msg, si, si->applet.ctx.table.proxy,
+			    !stats_dump_table_entry_to_buffer(&trash, si, si->applet.ctx.table.proxy,
 							      si->applet.ctx.table.entry))
 			    return 0;
 
@@ -3980,12 +3971,11 @@
 static int stats_dump_errors_to_buffer(struct stream_interface *si)
 {
 	extern const char *monthname[12];
-	struct chunk msg;
 
 	if (unlikely(si->ib->flags & (CF_WRITE_ERROR|CF_SHUTW)))
 		return 1;
 
-	chunk_init(&msg, trash, global.tune.bufsize);
+	chunk_reset(&trash);
 
 	if (!si->applet.ctx.errors.px) {
 		/* the function had not been called yet, let's prepare the
@@ -3994,12 +3984,12 @@
 		struct tm tm;
 
 		get_localtime(date.tv_sec, &tm);
-		chunk_appendf(&msg, "Total events captured on [%02d/%s/%04d:%02d:%02d:%02d.%03d] : %u\n",
+		chunk_appendf(&trash, "Total events captured on [%02d/%s/%04d:%02d:%02d:%02d.%03d] : %u\n",
 			     tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
 			     tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(date.tv_usec/1000),
 			     error_snapshot_id);
 
-		if (bi_putchk(si->ib, &msg) == -1) {
+		if (bi_putchk(si->ib, &trash) == -1) {
 			/* Socket buffer full. Let's try again later from the same point */
 			return 0;
 		}
@@ -4037,7 +4027,7 @@
 			int port;
 
 			get_localtime(es->when.tv_sec, &tm);
-			chunk_appendf(&msg, " \n[%02d/%s/%04d:%02d:%02d:%02d.%03d]",
+			chunk_appendf(&trash, " \n[%02d/%s/%04d:%02d:%02d:%02d.%03d]",
 				     tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
 				     tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(es->when.tv_usec/1000));
 
@@ -4052,7 +4042,7 @@
 
 			switch (si->applet.ctx.errors.buf) {
 			case 0:
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 					     " frontend %s (#%d): invalid request\n"
 					     "  backend %s (#%d)",
 					     si->applet.ctx.errors.px->id, si->applet.ctx.errors.px->uuid,
@@ -4060,7 +4050,7 @@
 					     (es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1);
 				break;
 			case 1:
-				chunk_appendf(&msg,
+				chunk_appendf(&trash,
 					     " backend %s (#%d) : invalid response\n"
 					     "  frontend %s (#%d)",
 					     si->applet.ctx.errors.px->id, si->applet.ctx.errors.px->uuid,
@@ -4068,7 +4058,7 @@
 				break;
 			}
 
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     ", server %s (#%d), event #%u\n"
 				     "  src %s:%d, session #%d, session flags 0x%08x\n"
 				     "  HTTP msg state %d, msg flags 0x%08x, tx flags 0x%08x\n"
@@ -4083,7 +4073,7 @@
 				     es->b_flags, es->b_out, es->b_tot,
 				     es->len, es->b_wrap, es->pos);
 
-			if (bi_putchk(si->ib, &msg) == -1) {
+			if (bi_putchk(si->ib, &trash) == -1) {
 				/* Socket buffer full. Let's try again later from the same point */
 				return 0;
 			}
@@ -4093,9 +4083,9 @@
 
 		if (si->applet.ctx.errors.sid != es->sid) {
 			/* the snapshot changed while we were dumping it */
-			chunk_appendf(&msg,
+			chunk_appendf(&trash,
 				     "  WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
-			if (bi_putchk(si->ib, &msg) == -1)
+			if (bi_putchk(si->ib, &trash) == -1)
 				return 0;
 			goto next;
 		}
@@ -4106,11 +4096,11 @@
 			int newline;
 
 			newline = si->applet.ctx.errors.bol;
-			newptr = dump_text_line(&msg, es->buf, sizeof(es->buf), es->len, &newline, si->applet.ctx.errors.ptr);
+			newptr = dump_text_line(&trash, es->buf, sizeof(es->buf), es->len, &newline, si->applet.ctx.errors.ptr);
 			if (newptr == si->applet.ctx.errors.ptr)
 				return 0;
 
-			if (bi_putchk(si->ib, &msg) == -1) {
+			if (bi_putchk(si->ib, &trash) == -1) {
 				/* Socket buffer full. Let's try again later from the same point */
 				return 0;
 			}
diff --git a/src/frontend.c b/src/frontend.c
index 0adbf8d..652718c 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -163,26 +163,25 @@
 
 	if (unlikely((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
 		char pn[INET6_ADDRSTRLEN];
-		int len = 0;
 
 		conn_get_from_addr(s->req->prod->conn);
 
 		switch (addr_to_str(&s->req->prod->conn->addr.from, pn, sizeof(pn))) {
 		case AF_INET:
 		case AF_INET6:
-			len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [%s:%d]\n",
-				      s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
-				      pn, get_host_port(&s->req->prod->conn->addr.from));
+			chunk_printf(&trash, "%08x:%s.accept(%04x)=%04x from [%s:%d]\n",
+			             s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
+			             pn, get_host_port(&s->req->prod->conn->addr.from));
 			break;
 		case AF_UNIX:
 			/* UNIX socket, only the destination is known */
-			len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [unix:%d]\n",
-				      s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
-				      s->listener->luid);
+			chunk_printf(&trash, "%08x:%s.accept(%04x)=%04x from [unix:%d]\n",
+			             s->uniq_id, s->fe->id, (unsigned short)s->listener->fd, (unsigned short)cfd,
+			             s->listener->luid);
 			break;
 		}
 
-		if (write(1, trash, len) < 0) /* shut gcc warning */;
+		if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
 	}
 
 	if (s->fe->mode == PR_MODE_HTTP)
diff --git a/src/haproxy.c b/src/haproxy.c
index 7606cec..2867ff9 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -155,7 +155,7 @@
 static int oldpids_sig; /* use USR1 or TERM */
 
 /* this is used to drain data, and as a temporary buffer for sprintf()... */
-char *trash = NULL;
+struct chunk trash = { };
 
 /* this buffer is always the same size as standard buffers and is used for
  * swapping data inside a buffer.
@@ -345,37 +345,37 @@
 
 		send_log(p, LOG_NOTICE, "SIGHUP received, dumping servers states for proxy %s.\n", p->id);
 		while (s) {
-			snprintf(trash, global.tune.bufsize,
-				 "SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %lld tot.",
-				 p->id, s->id,
-				 (s->state & SRV_RUNNING) ? "UP" : "DOWN",
-				 s->cur_sess, s->nbpend, s->counters.cum_sess);
-			Warning("%s\n", trash);
-			send_log(p, LOG_NOTICE, "%s\n", trash);
+			chunk_printf(&trash,
+			             "SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %lld tot.",
+			             p->id, s->id,
+			             (s->state & SRV_RUNNING) ? "UP" : "DOWN",
+			             s->cur_sess, s->nbpend, s->counters.cum_sess);
+			Warning("%s\n", trash.str);
+			send_log(p, LOG_NOTICE, "%s\n", trash.str);
 			s = s->next;
 		}
 
 		/* FIXME: those info are a bit outdated. We should be able to distinguish between FE and BE. */
 		if (!p->srv) {
-			snprintf(trash, global.tune.bufsize,
-				 "SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
-				 p->id,
-				 p->feconn, p->beconn, p->totpend, p->nbpend, p->fe_counters.cum_conn, p->be_counters.cum_conn);
+			chunk_printf(&trash,
+			             "SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
+			             p->id,
+			             p->feconn, p->beconn, p->totpend, p->nbpend, p->fe_counters.cum_conn, p->be_counters.cum_conn);
 		} else if (p->srv_act == 0) {
-			snprintf(trash, global.tune.bufsize,
-				 "SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
-				 p->id,
-				 (p->srv_bck) ? "is running on backup servers" : "has no server available",
-				 p->feconn, p->beconn, p->totpend, p->nbpend, p->fe_counters.cum_conn, p->be_counters.cum_conn);
+			chunk_printf(&trash,
+			             "SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
+			             p->id,
+			             (p->srv_bck) ? "is running on backup servers" : "has no server available",
+			             p->feconn, p->beconn, p->totpend, p->nbpend, p->fe_counters.cum_conn, p->be_counters.cum_conn);
 		} else {
-			snprintf(trash, global.tune.bufsize,
-				 "SIGHUP: Proxy %s has %d active servers and %d backup servers available."
-				 " Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
-				 p->id, p->srv_act, p->srv_bck,
-				 p->feconn, p->beconn, p->totpend, p->nbpend, p->fe_counters.cum_conn, p->be_counters.cum_conn);
+			chunk_printf(&trash,
+			             "SIGHUP: Proxy %s has %d active servers and %d backup servers available."
+			             " Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %lld+%lld.",
+			             p->id, p->srv_act, p->srv_bck,
+			             p->feconn, p->beconn, p->totpend, p->nbpend, p->fe_counters.cum_conn, p->be_counters.cum_conn);
 		}
-		Warning("%s\n", trash);
-		send_log(p, LOG_NOTICE, "%s\n", trash);
+		Warning("%s\n", trash.str);
+		send_log(p, LOG_NOTICE, "%s\n", trash.str);
 
 		p = p->next;
 	}
@@ -403,7 +403,7 @@
 	char *change_dir = NULL;
 	struct tm curtime;
 
-	trash = malloc(global.tune.bufsize);
+	chunk_init(&trash, malloc(global.tune.bufsize), global.tune.bufsize);
 
 	/* NB: POSIX does not make it mandatory for gethostname() to NULL-terminate
 	 * the string in case of truncation, and at least FreeBSD appears not to do
diff --git a/src/peers.c b/src/peers.c
index a84aba4..263cc8a 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -230,30 +230,30 @@
 				si->applet.st0 = PEER_SESSION_GETVERSION;
 				/* fall through */
 			case PEER_SESSION_GETVERSION:
-				reql = bo_getline(si->ob, trash, global.tune.bufsize);
+				reql = bo_getline(si->ob, trash.str, trash.size);
 				if (reql <= 0) { /* closed or EOL not found */
 					if (reql == 0)
 						goto out;
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				if (trash[reql-1] != '\n') {
+				if (trash.str[reql-1] != '\n') {
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				else if (reql > 1 && (trash[reql-2] == '\r'))
-					trash[reql-2] = 0;
+				else if (reql > 1 && (trash.str[reql-2] == '\r'))
+					trash.str[reql-2] = 0;
 				else
-					trash[reql-1] = 0;
+					trash.str[reql-1] = 0;
 
 				bo_skip(si->ob, reql);
 
 				/* test version */
-				if (strcmp(PEER_SESSION_PROTO_NAME " 1.0", trash) != 0) {
+				if (strcmp(PEER_SESSION_PROTO_NAME " 1.0", trash.str) != 0) {
 					si->applet.st0 = PEER_SESSION_EXIT;
 					si->applet.st1 = PEER_SESSION_ERRVERSION;
 					/* test protocol */
-					if (strncmp(PEER_SESSION_PROTO_NAME " ", trash, strlen(PEER_SESSION_PROTO_NAME)+1) != 0)
+					if (strncmp(PEER_SESSION_PROTO_NAME " ", trash.str, strlen(PEER_SESSION_PROTO_NAME)+1) != 0)
 						si->applet.st1 = PEER_SESSION_ERRPROTO;
 					goto switchstate;
 				}
@@ -261,26 +261,26 @@
 				si->applet.st0 = PEER_SESSION_GETHOST;
 				/* fall through */
 			case PEER_SESSION_GETHOST:
-				reql = bo_getline(si->ob, trash, global.tune.bufsize);
+				reql = bo_getline(si->ob, trash.str, trash.size);
 				if (reql <= 0) { /* closed or EOL not found */
 					if (reql == 0)
 						goto out;
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				if (trash[reql-1] != '\n') {
+				if (trash.str[reql-1] != '\n') {
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				else if (reql > 1 && (trash[reql-2] == '\r'))
-					trash[reql-2] = 0;
+				else if (reql > 1 && (trash.str[reql-2] == '\r'))
+					trash.str[reql-2] = 0;
 				else
-					trash[reql-1] = 0;
+					trash.str[reql-1] = 0;
 
 				bo_skip(si->ob, reql);
 
 				/* test hostname match */
-				if (strcmp(localpeer, trash) != 0) {
+				if (strcmp(localpeer, trash.str) != 0) {
 					si->applet.st0 = PEER_SESSION_EXIT;
 					si->applet.st1 = PEER_SESSION_ERRHOST;
 					goto switchstate;
@@ -291,27 +291,27 @@
 			case PEER_SESSION_GETPEER: {
 				struct peer *curpeer;
 				char *p;
-				reql = bo_getline(si->ob, trash, global.tune.bufsize);
+				reql = bo_getline(si->ob, trash.str, trash.size);
 				if (reql <= 0) { /* closed or EOL not found */
 					if (reql == 0)
 						goto out;
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				if (trash[reql-1] != '\n') {
+				if (trash.str[reql-1] != '\n') {
 					/* Incomplete line, we quit */
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				else if (reql > 1 && (trash[reql-2] == '\r'))
-					trash[reql-2] = 0;
+				else if (reql > 1 && (trash.str[reql-2] == '\r'))
+					trash.str[reql-2] = 0;
 				else
-					trash[reql-1] = 0;
+					trash.str[reql-1] = 0;
 
 				bo_skip(si->ob, reql);
 
 				/* parse line "<peer name> <pid>" */
-				p = strchr(trash, ' ');
+				p = strchr(trash.str, ' ');
 				if (!p) {
 					si->applet.st0 = PEER_SESSION_EXIT;
 					si->applet.st1 = PEER_SESSION_ERRPROTO;
@@ -321,7 +321,7 @@
 
 				/* lookup known peer */
 				for (curpeer = curpeers->remote; curpeer; curpeer = curpeer->next) {
-					if (strcmp(curpeer->id, trash) == 0)
+					if (strcmp(curpeer->id, trash.str) == 0)
 						break;
 				}
 
@@ -344,7 +344,7 @@
 				size_t key_size;
 				char *p;
 
-				reql = bo_getline(si->ob, trash, global.tune.bufsize);
+				reql = bo_getline(si->ob, trash.str, trash.size);
 				if (reql <= 0) { /* closed or EOL not found */
 					if (reql == 0)
 						goto out;
@@ -355,20 +355,20 @@
 				/* Re init si->conn->xprt_ctx to null, to handle correctly a release case */
 				si->conn->xprt_ctx = NULL;
 
-				if (trash[reql-1] != '\n') {
+				if (trash.str[reql-1] != '\n') {
 					/* Incomplete line, we quit */
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				else if (reql > 1 && (trash[reql-2] == '\r'))
-					trash[reql-2] = 0;
+				else if (reql > 1 && (trash.str[reql-2] == '\r'))
+					trash.str[reql-2] = 0;
 				else
-					trash[reql-1] = 0;
+					trash.str[reql-1] = 0;
 
 				bo_skip(si->ob, reql);
 
 				/* Parse line "<table name> <type> <size>" */
-				p = strchr(trash, ' ');
+				p = strchr(trash.str, ' ');
 				if (!p) {
 					si->applet.st0 = PEER_SESSION_EXIT;
 					si->applet.st1 = PEER_SESSION_ERRPROTO;
@@ -388,7 +388,7 @@
 				key_size = (size_t)atoi(p);
 				for (st = curpeers->tables; st; st = st->next) {
 					/* If table name matches */
-					if (strcmp(st->table->id, trash) == 0) {
+					if (strcmp(st->table->id, trash.str) == 0) {
 						/* If key size mismatches */
 						if (key_size != st->table->key_size) {
 							si->applet.st0 = PEER_SESSION_EXIT;
@@ -445,8 +445,8 @@
 			case PEER_SESSION_SENDSUCCESS:{
 				struct peer_session *ps = (struct peer_session *)si->conn->xprt_ctx;
 
-				repl = snprintf(trash, global.tune.bufsize, "%d\n", PEER_SESSION_SUCCESSCODE);
-				repl = bi_putblk(si->ib, trash, repl);
+				repl = snprintf(trash.str, trash.size, "%d\n", PEER_SESSION_SUCCESSCODE);
+				repl = bi_putblk(si->ib, trash.str, repl);
 				if (repl <= 0) {
 					if (repl == -1)
 						goto out;
@@ -496,7 +496,7 @@
 				struct peer_session *ps = (struct peer_session *)si->conn->xprt_ctx;
 
 				/* Send headers */
-				repl = snprintf(trash, global.tune.bufsize,
+				repl = snprintf(trash.str, trash.size,
 				                PEER_SESSION_PROTO_NAME " 1.0\n%s\n%s %d\n%s %lu %d\n",
 				                ps->peer->id,
 				                localpeer,
@@ -505,12 +505,12 @@
 				                ps->table->table->type,
 				                (int)ps->table->table->key_size);
 
-				if (repl >= global.tune.bufsize) {
+				if (repl >= trash.size) {
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
 
-				repl = bi_putblk(si->ib, trash, repl);
+				repl = bi_putblk(si->ib, trash.str, repl);
 				if (repl <= 0) {
 					if (repl == -1)
 						goto out;
@@ -528,27 +528,27 @@
 				if (si->ib->flags & CF_WRITE_PARTIAL)
 					ps->statuscode = PEER_SESSION_CONNECTEDCODE;
 
-				reql = bo_getline(si->ob, trash, global.tune.bufsize);
+				reql = bo_getline(si->ob, trash.str, trash.size);
 				if (reql <= 0) { /* closed or EOL not found */
 					if (reql == 0)
 						goto out;
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				if (trash[reql-1] != '\n') {
+				if (trash.str[reql-1] != '\n') {
 					/* Incomplete line, we quit */
 					si->applet.st0 = PEER_SESSION_END;
 					goto switchstate;
 				}
-				else if (reql > 1 && (trash[reql-2] == '\r'))
-					trash[reql-2] = 0;
+				else if (reql > 1 && (trash.str[reql-2] == '\r'))
+					trash.str[reql-2] = 0;
 				else
-					trash[reql-1] = 0;
+					trash.str[reql-1] = 0;
 
 				bo_skip(si->ob, reql);
 
 				/* Register status code */
-				ps->statuscode = atoi(trash);
+				ps->statuscode = atoi(trash.str);
 
 				/* Awake main task */
 				task_wakeup(ps->table->sync_task, TASK_WOKEN_MSG);
@@ -866,11 +866,11 @@
 				if (ps->pushack != ps->lastack) {
 					uint32_t netinteger;
 
-					trash[0] = 'A';
+					trash.str[0] = 'A';
 					netinteger = htonl(ps->pushack);
-					memcpy(&trash[1], &netinteger, sizeof(netinteger));
+					memcpy(&trash.str[1], &netinteger, sizeof(netinteger));
 
-					repl = bi_putblk(si->ib, trash, 1+sizeof(netinteger));
+					repl = bi_putblk(si->ib, trash.str, 1+sizeof(netinteger));
 					if (repl <= 0) {
 						/* no more write possible */
 						if (repl == -1)
@@ -903,10 +903,10 @@
 							}
 
 							ts = eb32_entry(eb, struct stksess, upd);
-							msglen = peer_prepare_datamsg(ts, ps, trash, global.tune.bufsize);
+							msglen = peer_prepare_datamsg(ts, ps, trash.str, trash.size);
 							if (msglen) {
 								/* message to buffer */
-								repl = bi_putblk(si->ib, trash, msglen);
+								repl = bi_putblk(si->ib, trash.str, msglen);
 								if (repl <= 0) {
 									/* no more write possible */
 									if (repl == -1)
@@ -937,10 +937,10 @@
 							}
 
 							ts = eb32_entry(eb, struct stksess, upd);
-							msglen = peer_prepare_datamsg(ts, ps, trash, global.tune.bufsize);
+							msglen = peer_prepare_datamsg(ts, ps, trash.str, trash.size);
 							if (msglen) {
 								/* message to buffer */
-								repl = bi_putblk(si->ib, trash, msglen);
+								repl = bi_putblk(si->ib, trash.str, msglen);
 								if (repl <= 0) {
 									/* no more write possible */
 									if (repl == -1)
@@ -995,10 +995,10 @@
 						}
 
 						ts = eb32_entry(eb, struct stksess, upd);
-						msglen = peer_prepare_datamsg(ts, ps, trash, global.tune.bufsize);
+						msglen = peer_prepare_datamsg(ts, ps, trash.str, trash.size);
 						if (msglen) {
 							/* message to buffer */
-							repl = bi_putblk(si->ib, trash, msglen);
+							repl = bi_putblk(si->ib, trash.str, msglen);
 							if (repl <= 0) {
 								/* no more write possible */
 								if (repl == -1)
@@ -1015,9 +1015,9 @@
 				goto out;
 			}
 			case PEER_SESSION_EXIT:
-				repl = snprintf(trash, global.tune.bufsize, "%d\n", si->applet.st1);
+				repl = snprintf(trash.str, trash.size, "%d\n", si->applet.st1);
 
-				if (bi_putblk(si->ib, trash, repl) == -1)
+				if (bi_putblk(si->ib, trash.str, repl) == -1)
 					goto out;
 				si->applet.st0 = PEER_SESSION_END;
 				/* fall through */
@@ -1229,7 +1229,7 @@
 	if ((s->req->buf = pool_alloc2(pool2_buffer)) == NULL)
 		goto out_fail_req_buf; /* no memory */
 
-	s->req->buf->size = global.tune.bufsize;
+	s->req->buf->size = trash.size;
 	channel_init(s->req);
 	s->req->prod = &s->si[0];
 	s->req->cons = &s->si[1];
@@ -1255,7 +1255,7 @@
 	if ((s->rep->buf = pool_alloc2(pool2_buffer)) == NULL)
 		goto out_fail_rep_buf; /* no memory */
 
-	s->rep->buf->size = global.tune.bufsize;
+	s->rep->buf->size = trash.size;
 	channel_init(s->rep);
 	s->rep->prod = &s->si[1];
 	s->rep->cons = &s->si[0];
diff --git a/src/proto_http.c b/src/proto_http.c
index e8046a5..14d076c 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -390,21 +390,19 @@
 #if defined(DEBUG_FSM)
 static void http_silent_debug(int line, struct session *s)
 {
-	int size = 0;
-	size += snprintf(trash + size, global.tune.bufsize - size,
-			 "[%04d] req: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld tf=%08x\n",
-			 line,
-			 s->si[0].state, s->si[0].fd, s->txn.req.msg_state, s->req->flags, s->req->analysers,
-			 s->req->buf->data, s->req->buf->size, s->req->l, s->req->w, s->req->r, s->req->buf->p, s->req->buf->o, s->req->to_forward, s->txn.flags);
-	write(-1, trash, size);
-	size = 0;
-	size += snprintf(trash + size, global.tune.bufsize - size,
-			 " %04d  rep: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld\n",
-			 line,
-			 s->si[1].state, s->si[1].fd, s->txn.rsp.msg_state, s->rep->flags, s->rep->analysers,
-			 s->rep->buf->data, s->rep->buf->size, s->rep->l, s->rep->w, s->rep->r, s->rep->buf->p, s->rep->buf->o, s->rep->to_forward);
+	chunk_printf(&trash,
+	             "[%04d] req: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld tf=%08x\n",
+	             line,
+	             s->si[0].state, s->si[0].fd, s->txn.req.msg_state, s->req->flags, s->req->analysers,
+	             s->req->buf->data, s->req->buf->size, s->req->l, s->req->w, s->req->r, s->req->buf->p, s->req->buf->o, s->req->to_forward, s->txn.flags);
+	write(-1, trash.str, trash.len);
 
-	write(-1, trash, size);
+	chunk_printf(&trash,
+	             " %04d  rep: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld\n",
+                     line,
+	             s->si[1].state, s->si[1].fd, s->txn.rsp.msg_state, s->rep->flags, s->rep->analysers,
+	             s->rep->buf->data, s->rep->buf->size, s->rep->l, s->rep->w, s->rep->r, s->rep->buf->p, s->rep->buf->o, s->rep->to_forward);
+	write(-1, trash.str, trash.len);
 }
 #else
 #define http_silent_debug(l,s)  do { } while (0)
@@ -761,27 +759,24 @@
 void perform_http_redirect(struct session *s, struct stream_interface *si)
 {
 	struct http_txn *txn;
-	struct chunk rdr;
 	struct server *srv;
 	char *path;
 	int len, rewind;
 
 	/* 1: create the response header */
-	rdr.len = strlen(HTTP_302);
-	rdr.str = trash;
-	rdr.size = global.tune.bufsize;
-	memcpy(rdr.str, HTTP_302, rdr.len);
+	trash.len = strlen(HTTP_302);
+	memcpy(trash.str, HTTP_302, trash.len);
 
 	srv = target_srv(&s->target);
 
 	/* 2: add the server's prefix */
-	if (rdr.len + srv->rdr_len > rdr.size)
+	if (trash.len + srv->rdr_len > trash.size)
 		return;
 
 	/* special prefix "/" means don't change URL */
 	if (srv->rdr_len != 1 || *srv->rdr_pfx != '/') {
-		memcpy(rdr.str + rdr.len, srv->rdr_pfx, srv->rdr_len);
-		rdr.len += srv->rdr_len;
+		memcpy(trash.str + trash.len, srv->rdr_pfx, srv->rdr_len);
+		trash.len += srv->rdr_len;
 	}
 
 	/* 3: add the request URI. Since it was already forwarded, we need
@@ -798,18 +793,18 @@
 	if (!path)
 		return;
 
-	if (rdr.len + len > rdr.size - 4) /* 4 for CRLF-CRLF */
+	if (trash.len + len > trash.size - 4) /* 4 for CRLF-CRLF */
 		return;
 
-	memcpy(rdr.str + rdr.len, path, len);
-	rdr.len += len;
+	memcpy(trash.str + trash.len, path, len);
+	trash.len += len;
 
 	if (unlikely(txn->flags & TX_USE_PX_CONN)) {
-		memcpy(rdr.str + rdr.len, "\r\nProxy-Connection: close\r\n\r\n", 29);
-		rdr.len += 29;
+		memcpy(trash.str + trash.len, "\r\nProxy-Connection: close\r\n\r\n", 29);
+		trash.len += 29;
 	} else {
-		memcpy(rdr.str + rdr.len, "\r\nConnection: close\r\n\r\n", 23);
-		rdr.len += 23;
+		memcpy(trash.str + trash.len, "\r\nConnection: close\r\n\r\n", 23);
+		trash.len += 23;
 	}
 
 	/* prepare to return without error. */
@@ -820,7 +815,7 @@
 	si->state    = SI_ST_CLO;
 
 	/* send the message */
-	http_server_error(s, si, SN_ERR_PRXCOND, SN_FINST_C, 302, &rdr);
+	http_server_error(s, si, SN_ERR_PRXCOND, SN_FINST_C, 302, &trash);
 
 	/* FIXME: we should increase a counter of redirects per server and per backend. */
 	if (srv)
@@ -2048,8 +2043,6 @@
 	struct http_msg *msg = &txn->rsp;
 	struct hdr_ctx ctx;
 	struct comp_type *comp_type;
-	char *hdr_val;
-	int hdr_len;
 
 	/* no common compression algorithm was found in request header */
 	if (s->comp_algo == NULL)
@@ -2059,7 +2052,6 @@
 	if (!(msg->flags & HTTP_MSGF_VER_11))
 		goto fail;
 
-	hdr_val = trash;
 	ctx.idx = 0;
 
 	/* Content-Length is null */
@@ -2105,12 +2097,12 @@
 	 * header.
 	 */
 	if (s->comp_algo->add_data != identity_add_data) {
-		hdr_len = 18;
-		memcpy(hdr_val, "Content-Encoding: ", hdr_len);
-		memcpy(hdr_val + hdr_len, s->comp_algo->name, s->comp_algo->name_len);
-		hdr_len += s->comp_algo->name_len;
-		hdr_val[hdr_len] = '\0';
-		http_header_add_tail2(&txn->rsp, &txn->hdr_idx, hdr_val, hdr_len);
+		trash.len = 18;
+		memcpy(trash.str, "Content-Encoding: ", trash.len);
+		memcpy(trash.str + trash.len, s->comp_algo->name, s->comp_algo->name_len);
+		trash.len += s->comp_algo->name_len;
+		trash.str[trash.len] = '\0';
+		http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.str, trash.len);
 	}
 
 	/* initialize compression */
@@ -3104,16 +3096,14 @@
 	 * either to pass or to access stats.
 	 */
 	if (http_req_last_rule && http_req_last_rule->action == HTTP_REQ_ACT_HTTP_AUTH) {
-		struct chunk msg;
 		char *realm = http_req_last_rule->http_auth.realm;
 
 		if (!realm)
 			realm = do_stats?STATS_DEFAULT_REALM:px->id;
 
-		sprintf(trash, (txn->flags & TX_USE_PX_CONN) ? HTTP_407_fmt : HTTP_401_fmt, realm);
-		chunk_initlen(&msg, trash, global.tune.bufsize, strlen(trash));
+		chunk_printf(&trash, (txn->flags & TX_USE_PX_CONN) ? HTTP_407_fmt : HTTP_401_fmt, realm);
 		txn->status = 401;
-		stream_int_retnclose(req->prod, &msg);
+		stream_int_retnclose(req->prod, &trash);
 		/* on 401 we still count one error, because normal browsing
 		 * won't significantly increase the counter but brute force
 		 * attempts will.
@@ -3219,7 +3209,6 @@
 		}
 
 		if (ret) {
-			struct chunk rdr = { .str = trash, .size = global.tune.bufsize, .len = 0 };
 			const char *msg_fmt;
 
 			/* build redirect message */
@@ -3236,7 +3225,7 @@
 				break;
 			}
 
-			if (unlikely(!chunk_strcpy(&rdr, msg_fmt)))
+			if (unlikely(!chunk_strcpy(&trash, msg_fmt)))
 				goto return_bad_req;
 
 			switch(rule->type) {
@@ -3275,32 +3264,32 @@
 				}
 
 				/* check if we can add scheme + "://" + host + path */
-				if (rdr.len + rule->rdr_len + 3 + hostlen + pathlen > rdr.size - 4)
+				if (trash.len + rule->rdr_len + 3 + hostlen + pathlen > trash.size - 4)
 					goto return_bad_req;
 
 				/* add scheme */
-				memcpy(rdr.str + rdr.len, rule->rdr_str, rule->rdr_len);
-				rdr.len += rule->rdr_len;
+				memcpy(trash.str + trash.len, rule->rdr_str, rule->rdr_len);
+				trash.len += rule->rdr_len;
 
 				/* add "://" */
-				memcpy(rdr.str + rdr.len, "://", 3);
-				rdr.len += 3;
+				memcpy(trash.str + trash.len, "://", 3);
+				trash.len += 3;
 
 				/* add host */
-				memcpy(rdr.str + rdr.len, host, hostlen);
-				rdr.len += hostlen;
+				memcpy(trash.str + trash.len, host, hostlen);
+				trash.len += hostlen;
 
 				/* add path */
-				memcpy(rdr.str + rdr.len, path, pathlen);
-				rdr.len += pathlen;
+				memcpy(trash.str + trash.len, path, pathlen);
+				trash.len += pathlen;
 
 				/* append a slash at the end of the location is needed and missing */
-				if (rdr.len && rdr.str[rdr.len - 1] != '/' &&
+				if (trash.len && trash.str[trash.len - 1] != '/' &&
 				    (rule->flags & REDIRECT_FLAG_APPEND_SLASH)) {
-					if (rdr.len > rdr.size - 5)
+					if (trash.len > trash.size - 5)
 						goto return_bad_req;
-					rdr.str[rdr.len] = '/';
-					rdr.len++;
+					trash.str[trash.len] = '/';
+					trash.len++;
 				}
 
 				break;
@@ -3328,7 +3317,7 @@
 					pathlen = 1;
 				}
 
-				if (rdr.len + rule->rdr_len + pathlen > rdr.size - 4)
+				if (trash.len + rule->rdr_len + pathlen > trash.size - 4)
 					goto return_bad_req;
 
 				/* add prefix. Note that if prefix == "/", we don't want to
@@ -3336,43 +3325,43 @@
 				 * configure a self-redirection.
 				 */
 				if (rule->rdr_len != 1 || *rule->rdr_str != '/') {
-					memcpy(rdr.str + rdr.len, rule->rdr_str, rule->rdr_len);
-					rdr.len += rule->rdr_len;
+					memcpy(trash.str + trash.len, rule->rdr_str, rule->rdr_len);
+					trash.len += rule->rdr_len;
 				}
 
 				/* add path */
-				memcpy(rdr.str + rdr.len, path, pathlen);
-				rdr.len += pathlen;
+				memcpy(trash.str + trash.len, path, pathlen);
+				trash.len += pathlen;
 
 				/* append a slash at the end of the location is needed and missing */
-				if (rdr.len && rdr.str[rdr.len - 1] != '/' &&
+				if (trash.len && trash.str[trash.len - 1] != '/' &&
 				    (rule->flags & REDIRECT_FLAG_APPEND_SLASH)) {
-					if (rdr.len > rdr.size - 5)
+					if (trash.len > trash.size - 5)
 						goto return_bad_req;
-					rdr.str[rdr.len] = '/';
-					rdr.len++;
+					trash.str[trash.len] = '/';
+					trash.len++;
 				}
 
 				break;
 			}
 			case REDIRECT_TYPE_LOCATION:
 			default:
-				if (rdr.len + rule->rdr_len > rdr.size - 4)
+				if (trash.len + rule->rdr_len > trash.size - 4)
 					goto return_bad_req;
 
 				/* add location */
-				memcpy(rdr.str + rdr.len, rule->rdr_str, rule->rdr_len);
-				rdr.len += rule->rdr_len;
+				memcpy(trash.str + trash.len, rule->rdr_str, rule->rdr_len);
+				trash.len += rule->rdr_len;
 				break;
 			}
 
 			if (rule->cookie_len) {
-				memcpy(rdr.str + rdr.len, "\r\nSet-Cookie: ", 14);
-				rdr.len += 14;
-				memcpy(rdr.str + rdr.len, rule->cookie_str, rule->cookie_len);
-				rdr.len += rule->cookie_len;
-				memcpy(rdr.str + rdr.len, "\r\n", 2);
-				rdr.len += 2;
+				memcpy(trash.str + trash.len, "\r\nSet-Cookie: ", 14);
+				trash.len += 14;
+				memcpy(trash.str + trash.len, rule->cookie_str, rule->cookie_len);
+				trash.len += rule->cookie_len;
+				memcpy(trash.str + trash.len, "\r\n", 2);
+				trash.len += 2;
 			}
 
 			/* add end of headers and the keep-alive/close status.
@@ -3392,16 +3381,16 @@
 				/* keep-alive possible */
 				if (!(msg->flags & HTTP_MSGF_VER_11)) {
 					if (unlikely(txn->flags & TX_USE_PX_CONN)) {
-						memcpy(rdr.str + rdr.len, "\r\nProxy-Connection: keep-alive", 30);
-						rdr.len += 30;
+						memcpy(trash.str + trash.len, "\r\nProxy-Connection: keep-alive", 30);
+						trash.len += 30;
 					} else {
-						memcpy(rdr.str + rdr.len, "\r\nConnection: keep-alive", 24);
-						rdr.len += 24;
+						memcpy(trash.str + trash.len, "\r\nConnection: keep-alive", 24);
+						trash.len += 24;
 					}
 				}
-				memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
-				rdr.len += 4;
-				bo_inject(req->prod->ob, rdr.str, rdr.len);
+				memcpy(trash.str + trash.len, "\r\n\r\n", 4);
+				trash.len += 4;
+				bo_inject(req->prod->ob, trash.str, trash.len);
 				/* "eat" the request */
 				bi_fast_delete(req->buf, msg->sov);
 				msg->sov = 0;
@@ -3413,13 +3402,13 @@
 			} else {
 				/* keep-alive not possible */
 				if (unlikely(txn->flags & TX_USE_PX_CONN)) {
-					memcpy(rdr.str + rdr.len, "\r\nProxy-Connection: close\r\n\r\n", 29);
-					rdr.len += 29;
+					memcpy(trash.str + trash.len, "\r\nProxy-Connection: close\r\n\r\n", 29);
+					trash.len += 29;
 				} else {
-					memcpy(rdr.str + rdr.len, "\r\nConnection: close\r\n\r\n", 23);
-					rdr.len += 23;
+					memcpy(trash.str + trash.len, "\r\nConnection: close\r\n\r\n", 23);
+					trash.len += 23;
 				}
-				stream_int_retnclose(req->prod, &rdr);
+				stream_int_retnclose(req->prod, &trash);
 				goto return_prx_cond;
 			}
 		}
@@ -3534,10 +3523,10 @@
 		build_logline(s, s->unique_id, UNIQUEID_LEN, &s->fe->format_unique_id);
 
 	if (s->fe->header_unique_id && s->unique_id) {
-		int ret = snprintf(trash, global.tune.bufsize, "%s: %s", s->fe->header_unique_id, s->unique_id);
-		if (ret < 0 || ret > global.tune.bufsize)
+		chunk_printf(&trash, "%s: %s", s->fe->header_unique_id, s->unique_id);
+		if (trash.len < 0)
 			goto return_bad_req;
-		if (unlikely(http_header_add_tail(&txn->req, &txn->hdr_idx, trash) < 0))
+		if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.str, trash.len) < 0))
 		   goto return_bad_req;
 	}
 
@@ -3576,14 +3565,14 @@
 				 */
 				if (s->be->fwdfor_hdr_len) {
 					len = s->be->fwdfor_hdr_len;
-					memcpy(trash, s->be->fwdfor_hdr_name, len);
+					memcpy(trash.str, s->be->fwdfor_hdr_name, len);
 				} else {
 					len = s->fe->fwdfor_hdr_len;
-					memcpy(trash, s->fe->fwdfor_hdr_name, len);
+					memcpy(trash.str, s->fe->fwdfor_hdr_name, len);
 				}
-				len += sprintf(trash + len, ": %d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
+				len += sprintf(trash.str + len, ": %d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
 
-				if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash, len) < 0))
+				if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.str, len) < 0))
 					goto return_bad_req;
 			}
 		}
@@ -3604,14 +3593,14 @@
 			 */
 			if (s->be->fwdfor_hdr_len) {
 				len = s->be->fwdfor_hdr_len;
-				memcpy(trash, s->be->fwdfor_hdr_name, len);
+				memcpy(trash.str, s->be->fwdfor_hdr_name, len);
 			} else {
 				len = s->fe->fwdfor_hdr_len;
-				memcpy(trash, s->fe->fwdfor_hdr_name, len);
+				memcpy(trash.str, s->fe->fwdfor_hdr_name, len);
 			}
-			len += sprintf(trash + len, ": %s", pn);
+			len += sprintf(trash.str + len, ": %s", pn);
 
-			if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash, len) < 0))
+			if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.str, len) < 0))
 				goto return_bad_req;
 		}
 	}
@@ -3647,14 +3636,14 @@
 				 */
 				if (s->be->orgto_hdr_len) {
 					len = s->be->orgto_hdr_len;
-					memcpy(trash, s->be->orgto_hdr_name, len);
+					memcpy(trash.str, s->be->orgto_hdr_name, len);
 				} else {
 					len = s->fe->orgto_hdr_len;
-					memcpy(trash, s->fe->orgto_hdr_name, len);
+					memcpy(trash.str, s->fe->orgto_hdr_name, len);
 				}
-				len += sprintf(trash + len, ": %d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
+				len += sprintf(trash.str + len, ": %d.%d.%d.%d", pn[0], pn[1], pn[2], pn[3]);
 
-				if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash, len) < 0))
+				if (unlikely(http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.str, len) < 0))
 					goto return_bad_req;
 			}
 		}
@@ -3957,13 +3946,13 @@
 	}
 
 	/* Add the new header requested with the server value */
-	hdr_val = trash;
+	hdr_val = trash.str;
 	memcpy(hdr_val, hdr_name, hdr_name_len);
 	hdr_val += hdr_name_len;
 	*hdr_val++ = ':';
 	*hdr_val++ = ' ';
-	hdr_val += strlcpy2(hdr_val, srv_name, trash + global.tune.bufsize - hdr_val);
-	http_header_add_tail2(&txn->req, &txn->hdr_idx, trash, hdr_val - trash);
+	hdr_val += strlcpy2(hdr_val, srv_name, trash.str + trash.size - hdr_val);
+	http_header_add_tail2(&txn->req, &txn->hdr_idx, trash.str, hdr_val - trash.str);
 
 	if (old_o) {
 		/* If this was a forwarded request, we must readjust the amount of
@@ -5347,7 +5336,6 @@
 		     (!t->be->cookie_maxlife && txn->cookie_first_date)) && // remove the first_date
 		    (!(t->be->ck_opts & PR_CK_POST) || (txn->meth == HTTP_METH_POST)) &&
 		    !(t->flags & SN_IGNORE_PRST)) {
-			int len;
 			/* the server is known, it's not the one the client requested, or the
 			 * cookie's last seen date needs to be refreshed. We have to
 			 * insert a set-cookie here, except if we want to insert only on POST
@@ -5355,41 +5343,43 @@
 			 * (eg: some backup servers) will return a full cookie removal request.
 			 */
 			if (!target_srv(&t->target)->cookie) {
-				len = sprintf(trash,
+				chunk_printf(&trash,
 					      "Set-Cookie: %s=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
 					      t->be->cookie_name);
 			}
 			else {
-				len = sprintf(trash, "Set-Cookie: %s=%s", t->be->cookie_name, target_srv(&t->target)->cookie);
+				chunk_printf(&trash, "Set-Cookie: %s=%s", t->be->cookie_name, target_srv(&t->target)->cookie);
 
 				if (t->be->cookie_maxidle || t->be->cookie_maxlife) {
 					/* emit last_date, which is mandatory */
-					trash[len++] = COOKIE_DELIM_DATE;
-					s30tob64((date.tv_sec+3) >> 2, trash + len); len += 5;
+					trash.str[trash.len++] = COOKIE_DELIM_DATE;
+					s30tob64((date.tv_sec+3) >> 2, trash.str + trash.len);
+					trash.len += 5;
+
 					if (t->be->cookie_maxlife) {
 						/* emit first_date, which is either the original one or
 						 * the current date.
 						 */
-						trash[len++] = COOKIE_DELIM_DATE;
+						trash.str[trash.len++] = COOKIE_DELIM_DATE;
 						s30tob64(txn->cookie_first_date ?
 							 txn->cookie_first_date >> 2 :
-							 (date.tv_sec+3) >> 2, trash + len);
-						len += 5;
+							 (date.tv_sec+3) >> 2, trash.str + trash.len);
+						trash.len += 5;
 					}
 				}
-				len += sprintf(trash + len, "; path=/");
+				chunk_appendf(&trash, "; path=/");
 			}
 
 			if (t->be->cookie_domain)
-				len += sprintf(trash+len, "; domain=%s", t->be->cookie_domain);
+				chunk_appendf(&trash, "; domain=%s", t->be->cookie_domain);
 
 			if (t->be->ck_opts & PR_CK_HTTPONLY)
-				len += sprintf(trash+len, "; HttpOnly");
+				chunk_appendf(&trash, "; HttpOnly");
 
 			if (t->be->ck_opts & PR_CK_SECURE)
-				len += sprintf(trash+len, "; Secure");
+				chunk_appendf(&trash, "; Secure");
 
-			if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash, len) < 0))
+			if (unlikely(http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.str, trash.len) < 0))
 				goto return_bad_resp;
 
 			txn->flags &= ~TX_SCK_MASK;
@@ -5800,7 +5790,7 @@
 	int cur_idx, old_idx, last_hdr;
 	struct http_txn *txn = &t->txn;
 	struct hdr_idx_elem *cur_hdr;
-	int len, delta;
+	int delta;
 
 	last_hdr = 0;
 
@@ -5882,8 +5872,8 @@
 				break;
 
 			case ACT_REPLACE:
-				len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-				delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash, len);
+				trash.len = exp_replace(trash.str, cur_ptr, exp->replace, pmatch);
+				delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash.str, trash.len);
 				/* FIXME: if the user adds a newline in the replacement, the
 				 * index will not be recalculated for now, and the new line
 				 * will not be counted as a new header.
@@ -5933,8 +5923,7 @@
 	char *cur_ptr, *cur_end;
 	int done;
 	struct http_txn *txn = &t->txn;
-	int len, delta;
-
+	int delta;
 
 	if (unlikely(txn->flags & (TX_CLDENY | TX_CLTARPIT)))
 		return 1;
@@ -6007,8 +5996,8 @@
 
 		case ACT_REPLACE:
 			*cur_end = term; /* restore the string terminator */
-			len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-			delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash, len);
+			trash.len = exp_replace(trash.str, cur_ptr, exp->replace, pmatch);
+			delta = buffer_replace2(req->buf, cur_ptr, cur_end, trash.str, trash.len);
 			/* FIXME: if the user adds a newline in the replacement, the
 			 * index will not be recalculated for now, and the new line
 			 * will not be counted as a new header.
@@ -6707,7 +6696,7 @@
 	int cur_idx, old_idx, last_hdr;
 	struct http_txn *txn = &t->txn;
 	struct hdr_idx_elem *cur_hdr;
-	int len, delta;
+	int delta;
 
 	last_hdr = 0;
 
@@ -6756,8 +6745,8 @@
 				break;
 
 			case ACT_REPLACE:
-				len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-				delta = buffer_replace2(rtr->buf, cur_ptr, cur_end, trash, len);
+				trash.len = exp_replace(trash.str, cur_ptr, exp->replace, pmatch);
+				delta = buffer_replace2(rtr->buf, cur_ptr, cur_end, trash.str, trash.len);
 				/* FIXME: if the user adds a newline in the replacement, the
 				 * index will not be recalculated for now, and the new line
 				 * will not be counted as a new header.
@@ -6805,7 +6794,7 @@
 	char *cur_ptr, *cur_end;
 	int done;
 	struct http_txn *txn = &t->txn;
-	int len, delta;
+	int delta;
 
 
 	if (unlikely(txn->flags & TX_SVDENY))
@@ -6846,8 +6835,8 @@
 
 		case ACT_REPLACE:
 			*cur_end = term; /* restore the string terminator */
-			len = exp_replace(trash, cur_ptr, exp->replace, pmatch);
-			delta = buffer_replace2(rtr->buf, cur_ptr, cur_end, trash, len);
+			trash.len = exp_replace(trash.str, cur_ptr, exp->replace, pmatch);
+			delta = buffer_replace2(rtr->buf, cur_ptr, cur_end, trash.str, trash.len);
 			/* FIXME: if the user adds a newline in the replacement, the
 			 * index will not be recalculated for now, and the new line
 			 * will not be counted as a new header.
@@ -7658,18 +7647,18 @@
  */
 void debug_hdr(const char *dir, struct session *t, const char *start, const char *end)
 {
-	int len, max;
-	len = sprintf(trash, "%08x:%s.%s[%04x:%04x]: ", t->uniq_id, t->be->id,
+	int max;
+	chunk_printf(&trash, "%08x:%s.%s[%04x:%04x]: ", t->uniq_id, t->be->id,
 		      dir, (unsigned  short)si_fd(t->req->prod), (unsigned short)si_fd(t->req->cons));
 
 	for (max = 0; start + max < end; max++)
 		if (start[max] == '\r' || start[max] == '\n')
 			break;
 
-	UBOUND(max, global.tune.bufsize - len - 3);
-	len += strlcpy2(trash + len, start, max + 1);
-	trash[len++] = '\n';
-	if (write(1, trash, len) < 0) /* shut gcc warning */;
+	UBOUND(max, trash.size - trash.len - 3);
+	trash.len += strlcpy2(trash.str + trash.len, start, max + 1);
+	trash.str[trash.len++] = '\n';
+	if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
 }
 
 /*
@@ -8377,9 +8366,9 @@
 		return smp_fetch_path(px, l4, l7, opt, args, smp);
 
 	/* OK we have the header value in ctx.line+ctx.val for ctx.vlen bytes */
-	memcpy(trash, ctx.line + ctx.val, ctx.vlen);
+	memcpy(trash.str, ctx.line + ctx.val, ctx.vlen);
 	smp->type = SMP_T_STR;
-	smp->data.str.str = trash;
+	smp->data.str.str = trash.str;
 	smp->data.str.len = ctx.vlen;
 
 	/* now retrieve the path */
diff --git a/src/session.c b/src/session.c
index 60c8426..840ad29 100644
--- a/src/session.c
+++ b/src/session.c
@@ -158,7 +158,7 @@
 		 *  - HEALTH mode without HTTP check => just send "OK"
 		 *  - TCP mode from monitoring address => just close
 		 */
-		recv(cfd, trash, global.tune.bufsize, MSG_DONTWAIT);
+		recv(cfd, trash.str, trash.size, MSG_DONTWAIT);
 		if (p->mode == PR_MODE_HTTP ||
 		    (p->mode == PR_MODE_HEALTH && (p->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK))
 			send(cfd, "HTTP/1.0 200 OK\r\n\r\n", 19, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_MORE);
@@ -2292,24 +2292,22 @@
 	if (unlikely((global.mode & MODE_DEBUG) &&
 		     (!(global.mode & MODE_QUIET) ||
 		      (global.mode & MODE_VERBOSE)))) {
-		int len;
-
 		if (s->si[1].state == SI_ST_CLO &&
 		    s->si[1].prev_state == SI_ST_EST) {
-			len = sprintf(trash, "%08x:%s.srvcls[%04x:%04x]\n",
+			chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
 				      s->uniq_id, s->be->id,
 				      (unsigned short)si_fd(&s->si[0]),
 				      (unsigned short)si_fd(&s->si[1]));
-			if (write(1, trash, len) < 0) /* shut gcc warning */;
+			if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
 		}
 
 		if (s->si[0].state == SI_ST_CLO &&
 		    s->si[0].prev_state == SI_ST_EST) {
-			len = sprintf(trash, "%08x:%s.clicls[%04x:%04x]\n",
+			chunk_printf(&trash, "%08x:%s.clicls[%04x:%04x]\n",
 				      s->uniq_id, s->be->id,
 				      (unsigned short)si_fd(&s->si[0]),
 				      (unsigned short)si_fd(&s->si[1]));
-			if (write(1, trash, len) < 0) /* shut gcc warning */;
+			if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
 		}
 	}
 
@@ -2412,11 +2410,10 @@
 
 	if (unlikely((global.mode & MODE_DEBUG) &&
 		     (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
-		int len;
-		len = sprintf(trash, "%08x:%s.closed[%04x:%04x]\n",
+		chunk_printf(&trash, "%08x:%s.closed[%04x:%04x]\n",
 			      s->uniq_id, s->be->id,
 			      (unsigned short)si_fd(s->req->prod), (unsigned short)si_fd(s->req->cons));
-		if (write(1, trash, len) < 0) /* shut gcc warning */;
+		if (write(1, trash.str, trash.len) < 0) /* shut gcc warning */;
 	}
 
 	s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 8c05126..bc4afc6 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -173,17 +173,17 @@
 	if (!servername)
 		return SSL_TLSEXT_ERR_NOACK;
 
-	for (i = 0; i < global.tune.bufsize; i++) {
+	for (i = 0; i < trash.size; i++) {
 		if (!servername[i])
 			break;
-		trash[i] = tolower(servername[i]);
-		if (!wildp && (trash[i] == '.'))
-			wildp = &trash[i];
+		trash.str[i] = tolower(servername[i]);
+		if (!wildp && (trash.str[i] == '.'))
+			wildp = &trash.str[i];
 	}
-	trash[i] = 0;
+	trash.str[i] = 0;
 
 	/* lookup in full qualified names */
-	node = ebst_lookup(&s->sni_ctx, trash);
+	node = ebst_lookup(&s->sni_ctx, trash.str);
 	if (!node) {
 		if (!wildp)
 			return SSL_TLSEXT_ERR_ALERT_WARNING;
@@ -887,7 +887,7 @@
 			 * TCP sockets. We first try to drain possibly pending
 			 * data to avoid this as much as possible.
 			 */
-			ret = recv(conn->t.sock.fd, trash, global.tune.bufsize, MSG_NOSIGNAL|MSG_DONTWAIT);
+			ret = recv(conn->t.sock.fd, trash.str, trash.size, MSG_NOSIGNAL|MSG_DONTWAIT);
 			goto out_error;
 		}
 	}
diff --git a/src/stream_interface.c b/src/stream_interface.c
index b075065..cb3e7ea 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -507,7 +507,7 @@
 		 * (which is recomputed every time since it's constant). If
 		 * it is positive, it means we have to send from the start.
 		 */
-		ret = make_proxy_line(trash, global.tune.bufsize, &si->ob->prod->conn->addr.from, &si->ob->prod->conn->addr.to);
+		ret = make_proxy_line(trash.str, trash.size, &si->ob->prod->conn->addr.from, &si->ob->prod->conn->addr.to);
 		if (!ret)
 			goto out_error;
 
@@ -517,7 +517,7 @@
 		/* we have to send trash from (ret+sp for -sp bytes). If the
 		 * data layer has a pending write, we'll also set MSG_MORE.
 		 */
-		ret = send(conn->t.sock.fd, trash + ret + si->send_proxy_ofs, -si->send_proxy_ofs,
+		ret = send(conn->t.sock.fd, trash.str + ret + si->send_proxy_ofs, -si->send_proxy_ofs,
 			   (conn->flags & CO_FL_DATA_WR_ENA) ? MSG_MORE : 0);
 
 		if (ret == 0)