[MEDIUM] make the http server error function a pointer in the session

It was a bit awkward to have session.c call return_srv_error() for
HTTP error messages related to servers. The function has been adapted
to be passed a pointer to the faulty stream interface, and is now a
pointer in the session. It is possible that in the future, it will
become a callback in the stream interface itself.
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index 3addf3f..72a5e3c 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -84,7 +84,7 @@
 		      struct hdr_ctx *ctx);
 void http_sess_log(struct session *s);
 void perform_http_redirect(struct session *s, struct stream_interface *si);
-void return_srv_error(struct session *s, int err_type);
+void http_return_srv_error(struct session *s, struct stream_interface *si);
 
 #endif /* _PROTO_PROTO_HTTP_H */
 
diff --git a/include/types/session.h b/include/types/session.h
index 92bfa06..83d0a45 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -188,7 +188,9 @@
 		long long bytes_in;		/* number of bytes transferred from the client to the server */
 		long long bytes_out;		/* number of bytes transferred from the server to the client */
 	} logs;
-	void (*do_log)(struct session *s);	/* the function to call in order to log */
+	void (*do_log)(struct session *s);	/* the function to call in order to log (or NULL) */
+	void (*srv_error)(struct session *s,	/* the function to call upon unrecoverable server errors (or NULL) */
+			  struct stream_interface *si);
 	short int data_source;			/* where to get the data we generate ourselves */
 	short int data_state;			/* where to get the data we generate ourselves */
 	union {
diff --git a/src/client.c b/src/client.c
index bc7b254..bf7f55c 100644
--- a/src/client.c
+++ b/src/client.c
@@ -212,6 +212,11 @@
 		else
 			s->do_log = tcp_sess_log;
 
+		if (p->mode == PR_MODE_HTTP)
+			s->srv_error = http_return_srv_error;
+		else
+			s->srv_error = NULL;
+
 		s->logs.accept_date = date; /* user-visible date for logging */
 		s->logs.tv_accept = now;  /* corrected date for internal use */
 		tv_zero(&s->logs.tv_request);
diff --git a/src/proto_http.c b/src/proto_http.c
index 3991e41..b526076 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -696,7 +696,7 @@
 		s->srv->cum_sess++;
 }
 
-/* Return the error message corresponding to err_type. It is assumed
+/* Return the error message corresponding to si->err_type. It is assumed
  * that the server side is closed. Note that err_type is actually a
  * bitmask, where almost only aborts may be cumulated with other
  * values. We consider that aborted operations are more important
@@ -705,9 +705,9 @@
  * being cumulated. It should normally not be possible to have multiple
  * aborts at once, but just in case, the first one in sequence is reported.
  */
-void return_srv_error(struct session *s, int err_type)
+void http_return_srv_error(struct session *s, struct stream_interface *si)
 {
-	struct stream_interface *si = &s->si[1];
+	int err_type = si->err_type;
 
 	if (err_type & SI_ET_QUEUE_ABRT)
 		http_server_error(s, si, SN_ERR_CLICL, SN_FINST_Q,
diff --git a/src/session.c b/src/session.c
index 1eb7b69..0550de1 100644
--- a/src/session.c
+++ b/src/session.c
@@ -246,7 +246,8 @@
 		si->ib->flags |= BF_READ_ERROR;
 
 		si->state = SI_ST_CLO;
-		return_srv_error(s, si->err_type);
+		if (s->srv_error)
+			s->srv_error(s, si);
 		return 0;
 	}
 
@@ -397,7 +398,8 @@
 
 			/* no session was ever accounted for this server */
 			si->state = SI_ST_CLO;
-			return_srv_error(s, si->err_type);
+			if (s->srv_error)
+				s->srv_error(s, si);
 			return;
 		}
 
@@ -443,7 +445,8 @@
 			if (!si->err_type)
 				si->err_type = SI_ET_QUEUE_TO;
 			si->state = SI_ST_CLO;
-			return_srv_error(s, si->err_type);
+			if (s->srv_error)
+				s->srv_error(s, si);
 			return;
 		}
 
@@ -458,7 +461,8 @@
 			si->shutw(si);
 			si->err_type |= SI_ET_QUEUE_ABRT;
 			si->state = SI_ST_CLO;
-			return_srv_error(s, si->err_type);
+			if (s->srv_error)
+				s->srv_error(s, si);
 			return;
 		}
 
@@ -476,7 +480,8 @@
 			si->shutw(si);
 			si->err_type |= SI_ET_CONN_ABRT;
 			si->state = SI_ST_CLO;
-			return_srv_error(s, si->err_type);
+			if (s->srv_error)
+				s->srv_error(s, si);
 			return;
 		}
 
@@ -529,7 +534,8 @@
 		if (!si->err_type)
 			si->err_type = SI_ET_CONN_OTHER;
 		si->state = SI_ST_CLO;
-		return_srv_error(s, si->err_type);
+		if (s->srv_error)
+			s->srv_error(s, si);
 		return;
 	}