BUG/MINOR: applet: Notify the other side if data were consumed by an applet

If an applet consumed output data (the amount of output data has changed
between before and after the call to the applet), the producer is
notified. It means CF_WRITE_PARTIAL and CF_WROTE_DATA are set on the output
channel and the opposite stream interface is notified some room was made in
its input buffer. This way, it is no longer the applet responsibility to
take care of it. However, it doesn't matter if the applet does the same.

Said like that, it looks like an improvement not a bug. But it really fixes
a bug in the lua, for HTTP applets. Indeed, applet:receive() and
applet:getline() are buggy for HTTP applets. Data are consumed but the
producer is not notified. It means if the payload is not fully received in
one time, the applet may be blocked because the producer remains blocked (it
is time dependent).

This patch must be backported as far as 2.0 (only for the HTX part).

(cherry picked from commit 1eedf9b4cb71da642399ae1efbfad2c1cdad6c33)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit fffd9d8c7c7a1ff3a0b147ce28c4d960c48dc5d0)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 48da8402235bfd3464123a1f881e04174cda93f4)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/applet.c b/src/applet.c
index 0483386..4ff3893 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -61,6 +61,7 @@
 	struct appctx *app = context;
 	struct stream_interface *si = app->owner;
 	unsigned int rate;
+	size_t count;
 
 	if (app->state & APPLET_WANT_DIE) {
 		__appctx_free(app);
@@ -83,8 +84,17 @@
 	if (!si_alloc_ibuf(si, &app->buffer_wait))
 		si_rx_endp_more(si);
 
+	count = co_data(si_oc(si));
 	app->applet->fct(app);
 
+	/* now check if the applet has released some room and forgot to
+	 * notify the other side about it.
+	 */
+	if (count != co_data(si_oc(si))) {
+		si_oc(si)->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
+		si_rx_room_rdy(si_opposite(si));
+	}
+
 	/* measure the call rate and check for anomalies when too high */
 	rate = update_freq_ctr(&app->call_rate, 1);
 	if (rate >= 100000 && app->call_rate.prev_ctr && // looped more than 100k times over last second