]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] fix error response in case of server error
authorWilly Tarreau <w@1wt.eu>
Tue, 2 Feb 2010 08:57:24 +0000 (09:57 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 2 Feb 2010 09:04:19 +0000 (10:04 +0100)
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).

src/proto_http.c

index 821bf8912dba9b71774fe8b18c3f5d281a9666c3..e502bffe1307284af114d0d2b6b8702f8984f976 100644 (file)
@@ -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;