From: Willy Tarreau Date: Tue, 2 Feb 2010 08:57:24 +0000 (+0100) Subject: [BUG] fix error response in case of server error X-Git-Tag: v1.4-rc1~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0b89fbb076c2e3d6f27b147dced692164a4b9e82;p=thirdparty%2Fhaproxy.git [BUG] fix error response in case of server error The fix below was incomplete : commit d5fd51c75be6479539228f84377622a986b23be2 [BUG] http_server_error() must not purge a previous pending response This can cause parts of responses to be truncated in case of pipelined requests if the second request generates an error before the first request is completely flushed. Pending response data being rejected was still sent, causing inappropriate error responses in case of error while parsing a response header. We must purge pending data from the response buffer that were not scheduled to be sent (l - send_max). --- diff --git a/src/proto_http.c b/src/proto_http.c index 821bf8912d..e502bffe13 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -634,7 +634,6 @@ static void http_server_error(struct session *t, struct stream_interface *si, buffer_abort(si->ob); buffer_auto_close(si->ob); buffer_erase(si->ob); - buffer_erase(si->ob); buffer_auto_close(si->ib); buffer_auto_read(si->ib); if (status > 0 && msg) { @@ -4333,6 +4332,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) rep->analysers = 0; txn->status = 502; rep->prod->flags |= SI_FL_NOLINGER; + buffer_ignore(rep, rep->l - rep->send_max); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502)); if (!(s->flags & SN_ERR_MASK)) @@ -4363,6 +4363,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) rep->analysers = 0; txn->status = 502; rep->prod->flags |= SI_FL_NOLINGER; + buffer_ignore(rep, rep->l - rep->send_max); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502)); if (!(s->flags & SN_ERR_MASK)) @@ -4387,6 +4388,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) rep->analysers = 0; txn->status = 504; rep->prod->flags |= SI_FL_NOLINGER; + buffer_ignore(rep, rep->l - rep->send_max); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_504)); if (!(s->flags & SN_ERR_MASK)) @@ -4411,6 +4413,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) rep->analysers = 0; txn->status = 502; rep->prod->flags |= SI_FL_NOLINGER; + buffer_ignore(rep, rep->l - rep->send_max); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502)); if (!(s->flags & SN_ERR_MASK)) @@ -4737,6 +4740,7 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s rep->analysers = 0; txn->status = 502; rep->prod->flags |= SI_FL_NOLINGER; + buffer_ignore(rep, rep->l - rep->send_max); stream_int_retnclose(rep->cons, error_message(t, HTTP_ERR_502)); if (!(t->flags & SN_ERR_MASK)) t->flags |= SN_ERR_PRXCOND;