[MINOR] stats: report HTTP message state and buffer flags in error dumps

Debugging parsing errors can be greatly improved if we know what the parser
state was and what the buffer flags were (especially for closed inputs/outputs
and full buffers). Let's add that to the error snapshots.
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index e7181ec..417d5e6 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -91,7 +91,7 @@
 void http_return_srv_error(struct session *s, struct stream_interface *si);
 void http_capture_bad_message(struct error_snapshot *es, struct session *s,
                               struct buffer *buf, struct http_msg *msg,
-			      struct proxy *other_end);
+			      int state, struct proxy *other_end);
 unsigned int get_ip_from_hdr2(struct http_msg *msg, const char *hname, int hlen,
 			      struct hdr_idx *idx, int occ);
 
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 9704783..89cb09b 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -161,6 +161,8 @@
 	unsigned int len;		/* original length of the last invalid request/response */
 	unsigned int pos;		/* position of the first invalid character */
 	unsigned int sid;		/* ID of the faulty session */
+	unsigned int state;		/* message state before the error (when saved) */
+	unsigned int flags;		/* buffer flags */
 	struct server *srv;		/* server associated with the error (or NULL) */
 	struct proxy *oe;		/* other end = frontend or backend involved */
 	struct sockaddr_storage src;	/* client's address */
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 2695184..da29809 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -3477,23 +3477,27 @@
 				chunk_printf(&msg,
 					     " frontend %s (#%d): invalid request\n"
 					     "  src %s, session #%d, backend %s (#%d), server %s (#%d)\n"
+					     "  HTTP internal state %d, buffer flags 0x%08x\n"
 					     "  request length %d bytes, error at position %d:\n \n",
 					     s->data_ctx.errors.px->id, s->data_ctx.errors.px->uuid,
 					     pn, es->sid, (es->oe->cap & PR_CAP_BE) ? es->oe->id : "<NONE>",
 					     (es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1,
 					     es->srv ? es->srv->id : "<NONE>",
 					     es->srv ? es->srv->puid : -1,
+					     es->state, es->flags,
 					     es->len, es->pos);
 				break;
 			case 1:
 				chunk_printf(&msg,
 					     " backend %s (#%d) : invalid response\n"
 					     "  src %s, session #%d, frontend %s (#%d), server %s (#%d)\n"
+					     "  HTTP internal state %d, buffer flags 0x%08x\n"
 					     "  response length %d bytes, error at position %d:\n \n",
 					     s->data_ctx.errors.px->id, s->data_ctx.errors.px->uuid,
 					     pn, es->sid, es->oe->id, es->oe->uuid,
 					     es->srv ? es->srv->id : "<NONE>",
 					     es->srv ? es->srv->puid : -1,
+					     es->state, es->flags,
 					     es->len, es->pos);
 				break;
 			}
diff --git a/src/proto_http.c b/src/proto_http.c
index 4dcefca..893f8da 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -2487,7 +2487,7 @@
 
 			/* we cannot return any message on error */
 			if (msg->err_pos >= 0) {
-				http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
+				http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe);
 				session_inc_http_err_ctr(s);
 			}
 
@@ -2515,7 +2515,7 @@
 
 			/* read timeout : give up with an error message. */
 			if (msg->err_pos >= 0) {
-				http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
+				http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe);
 				session_inc_http_err_ctr(s);
 			}
 			txn->status = 408;
@@ -2543,7 +2543,7 @@
 				goto failed_keep_alive;
 
 			if (msg->err_pos >= 0)
-				http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
+				http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe);
 			txn->status = 400;
 			stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
 			msg->msg_state = HTTP_MSG_ERROR;
@@ -2625,7 +2625,7 @@
 	 * to block on that, so we have to capture it now.
 	 */
 	if (unlikely(msg->err_pos >= 0))
-		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
+		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe);
 
 	/*
 	 * 1: identify the method
@@ -2821,7 +2821,7 @@
 		/* we detected a parsing error. We want to archive this request
 		 * in the dedicated proxy area for later troubleshooting.
 		 */
-		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
+		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe);
 	}
 
 	txn->req.msg_state = HTTP_MSG_ERROR;
@@ -3375,7 +3375,7 @@
 		/* we detected a parsing error. We want to archive this request
 		 * in the dedicated proxy area for later troubleshooting.
 		 */
-		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
+		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe);
 	}
 
 	txn->req.msg_state = HTTP_MSG_ERROR;
@@ -3626,7 +3626,7 @@
 		/* we detected a parsing error. We want to archive this request
 		 * in the dedicated proxy area for later troubleshooting.
 		 */
-		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, s->fe);
+		http_capture_bad_message(&s->fe->invalid_req, s, req, msg, msg->msg_state, s->fe);
 	}
 
 	txn->req.msg_state = HTTP_MSG_ERROR;
@@ -4591,7 +4591,7 @@
 			 */
 		hdr_response_bad:
 			if (msg->msg_state == HTTP_MSG_ERROR || msg->err_pos >= 0)
-				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe);
+				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe);
 
 			s->be->counters.failed_resp++;
 			if (s->srv) {
@@ -4622,7 +4622,7 @@
 		/* read error */
 		else if (rep->flags & BF_READ_ERROR) {
 			if (msg->err_pos >= 0)
-				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe);
+				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe);
 
 			s->be->counters.failed_resp++;
 			if (s->srv) {
@@ -4647,7 +4647,7 @@
 		/* read timeout : return a 504 to the client. */
 		else if (rep->flags & BF_READ_TIMEOUT) {
 			if (msg->err_pos >= 0)
-				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe);
+				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe);
 
 			s->be->counters.failed_resp++;
 			if (s->srv) {
@@ -4672,7 +4672,7 @@
 		/* close from server */
 		else if (rep->flags & BF_SHUTR) {
 			if (msg->err_pos >= 0)
-				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe);
+				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe);
 
 			s->be->counters.failed_resp++;
 			if (s->srv) {
@@ -4697,7 +4697,7 @@
 		/* write error to client (we don't send any message then) */
 		else if (rep->flags & BF_WRITE_ERROR) {
 			if (msg->err_pos >= 0)
-				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe);
+				http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe);
 
 			s->be->counters.failed_resp++;
 			rep->analysers = 0;
@@ -4722,7 +4722,7 @@
 	 */
 
 	if (unlikely(msg->err_pos >= 0))
-		http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, s->fe);
+		http_capture_bad_message(&s->be->invalid_rep, s, rep, msg, msg->msg_state, s->fe);
 
 	/*
 	 * 1: get the status code
@@ -7200,7 +7200,7 @@
  */
 void http_capture_bad_message(struct error_snapshot *es, struct session *s,
                               struct buffer *buf, struct http_msg *msg,
-			      struct proxy *other_end)
+			      int state, struct proxy *other_end)
 {
 	es->len = buf->r - (buf->data + msg->som);
 	memcpy(es->buf, buf->data + msg->som, MIN(es->len, sizeof(es->buf)));
@@ -7213,6 +7213,8 @@
 	es->srv  = s->srv;
 	es->oe   = other_end;
 	es->src  = s->cli_addr;
+	es->state = state;
+	es->flags = buf->flags;
 }
 
 /* return the IP address pointed to by occurrence <occ> of header <hname> in