MINOR: http-ana: Add a function to set HTTP termination flags

There is already a function to set termination flags but it is not well
suited for HTTP streams. So a function, dedicated to the HTTP analysis, was
added. This way, this new function will be called for HTTP analysers on
error. And if the error is not caugth at this stage, the generic function
will still be called from process_stream().

Here, by default a PRXCOND error is reported and depending on the stream
state, the reson will be set accordingly:

  * If the backend SC is in INI state, SF_FINST_T is reported on tarpit and
    SF_FINST_R otherwise.

  * SF_FINST_Q is the server connection is queued

  * SF_FINST_C in any connection attempt state (REQ/TAR/ASS/CONN/CER/RDY).
    Except for applets, a SF_FINST_R is reported.

  * Once the server connection is established, SF_FINST_H is reported while
    HTTP_MSG_DATA state on the response side.

  * SF_FINST_L is reported if the response is in HTTP_MSG_DONE state or
    higher and a client error/timeout was reported.

  * Otherwise SF_FINST_D is reported.
diff --git a/include/haproxy/http_ana.h b/include/haproxy/http_ana.h
index 7a1b944..cbff545 100644
--- a/include/haproxy/http_ana.h
+++ b/include/haproxy/http_ana.h
@@ -62,6 +62,8 @@
 struct http_txn *http_create_txn(struct stream *s);
 void http_destroy_txn(struct stream *s);
 
+void http_set_term_flags(struct stream *s);
+
 /* for debugging, reports the HTTP/1 message state name (legacy version) */
 static inline const char *h1_msg_state_str(enum h1_state msg_state)
 {
diff --git a/src/http_ana.c b/src/http_ana.c
index 44c2953..873064d 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -5249,6 +5249,53 @@
 }
 
 
+void http_set_term_flags(struct stream *s)
+{
+	if (!(s->flags & SF_ERR_MASK))
+		s->flags |= SF_ERR_PRXCOND;
+
+	if (!(s->flags & SF_FINST_MASK)) {
+		if (s->scb->state == SC_ST_INI) {
+			/* Before any connection attempt on the server side, we
+			 * are still in the request analysis. Just take case to
+			 * detect tarpit error
+			 */
+			if (s->req.analysers & AN_REQ_HTTP_TARPIT)
+				s->flags |= SF_FINST_T;
+			else
+				s->flags |= SF_FINST_R;
+		}
+		else if (s->scb->state == SC_ST_QUE)
+			s->flags |= SF_FINST_Q;
+		else if (sc_state_in(s->scb->state, SC_SB_REQ|SC_SB_TAR|SC_SB_ASS|SC_SB_CON|SC_SB_CER|SC_SB_RDY)) {
+			if (unlikely(objt_applet(s->target))) {
+				s->flags |= SF_FINST_R;
+			}
+			else
+				s->flags |= SF_FINST_C;
+		}
+		else {
+			if (s->txn->rsp.msg_state < HTTP_MSG_DATA) {
+				/* We are still processing the response headers */
+				s->flags |= SF_FINST_H;
+			}
+			// (res >= done) & (res->flags & shutw)
+			else if (s->txn->rsp.msg_state >= HTTP_MSG_DONE &&
+				 (s->flags & (SF_ERR_CLITO|SF_ERR_CLICL))) {
+				/* A client error was reported and we are
+				 * transmitting the last block of data
+				 */
+				s->flags |= SF_FINST_L;
+			}
+			else {
+				/* Otherwise we are in DATA phase on both sides */
+				s->flags |= SF_FINST_D;
+			}
+		}
+	}
+}
+
+
 DECLARE_POOL(pool_head_http_txn, "http_txn", sizeof(struct http_txn));
 
 /*