Le 16/06/2017 à 16:19, Christopher Faulet a écrit :
Le 16/06/2017 à 13:29, Juan Pablo Mora a écrit :
Linux version:

Red Hat Enterprise Linux Server release 5.11 (Tikanga)

Linux dpoweb08 2.6.18-417.el5 #1 SMP Sat Nov 19 14:54:59 EST 2016 x86_64
x86_64 x86_64 GNU/Linux

HAProxy versión: 1.7.5

Summary:

After upgrading to HAProxy 1.7.5, requests with "SD" status in logs have
started to appear in one webservice. There have been no changes to the
webservice we invoke. The log shows:

Jun 16 12:41:06 localhost.lognet.pre.logalty.es haproxy[17315]:
172.31.2.70:59365 [16/Jun/2017:12:41:06.890] HTTP_INTERNO BUS/BUS1
1/0/0/65/75 200 225565 390 - - SD-- 12/2/0/0/0 0/0 {|Keep-Alive|174|}
{|close|} "POST
/lgt/lgtbus/rest/private/receiverServiceLight/getSignedBinaryContent
HTTP/1.1"

The same POST in HAProxy 1.5.12 ends with “ 200 “ and “----“.


Hi,

Bernard McCormack has already reported the same issue. I'm on it. I
approximately identified the problem but I need more time to fully
understand it and to find the best way to fix it.

The bug occurs where we are waiting the end of the response to
synchronize the request and the response. The close on the server side
is detected as an error when there is no content-length nor
transfer-encoding header. But it is a bit tricky because it is partly a
timing issue. Depending when the connection close is catched, an error
is triggered or not.

So I'm on it. Stay tuned.


Hi guys,

I worked on this problem. Could you check if the attached patch fixes your bug ?

Thanks,
--
Christopher Faulet
diff --git a/src/proto_http.c b/src/proto_http.c
index e5f67e5..521743a 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -6958,14 +6958,6 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
 	if ((msg->flags & HTTP_MSGF_TE_CHNK) || (msg->flags & HTTP_MSGF_COMPRESSING))
 		res->flags |= CF_EXPECT_MORE;
 
-	/* If there is neither content-length, nor transfer-encoding header
-	 * _AND_ there is no data filtering, we can safely forward all data
-	 * indefinitely. */
-	if (!(msg->flags & HTTP_MSGF_XFER_LEN) && !HAS_DATA_FILTERS(s, res)) {
-		buffer_flush(res->buf);
-		channel_forward_forever(res);
-	}
-
 	/* the stream handler will take care of timeouts and errors */
 	return 0;
 
@@ -7042,9 +7034,20 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg)
 		goto missing_data_or_waiting;
 	}
 
-	/* The server still sending data that should be filtered */
-	if (!(msg->flags & HTTP_MSGF_XFER_LEN) && !(chn->flags & CF_SHUTR))
-		goto missing_data_or_waiting;
+	/* This check can only be true for a response. HTTP_MSGF_XFER_LEN is
+	 * always set for a request. */
+	if (!(msg->flags & HTTP_MSGF_XFER_LEN)) {
+		/* The server still sending data that should be filtered */
+		if (!(chn->flags & CF_SHUTR) && HAS_DATA_FILTERS(s, chn))
+			goto missing_data_or_waiting;
+		/* There is no data filtering (or no more data to filter) but at
+		 * least one active filter on the stream. So force infinite
+		 * forwarding here. */
+		else if (HAS_FILTERS(s)) {
+			buffer_flush(chn->buf);
+			channel_forward_forever(chn);
+		}
+	}
 
 	msg->msg_state = HTTP_MSG_ENDING;
 

Reply via email to