]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] http: don't wait for response data to leave buffer is client has left
authorWilly Tarreau <w@1wt.eu>
Fri, 5 Mar 2010 09:41:54 +0000 (10:41 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 5 Mar 2010 09:57:48 +0000 (10:57 +0100)
In case of pipelined requests, if the client aborts before reading response
N-1, haproxy waits forever for the data to leave the buffer before parsing
the next response.

src/proto_http.c

index 0131700e3b7824f8d2cf51d58b11ed76af8a4794..fea3d362e60d05346abae95899c10249997bd737 100644 (file)
@@ -2359,6 +2359,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
                             req->r < req->lr ||
                             req->r > req->data + req->size - global.tune.maxrewrite)) {
                        if (req->send_max) {
+                               if (req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
+                                       goto failed_keep_alive;
                                /* some data has still not left the buffer, wake us once that's done */
                                buffer_dont_connect(req);
                                req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
@@ -2380,6 +2382,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
                             s->rep->r < s->rep->lr ||
                             s->rep->r > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
                        if (s->rep->send_max) {
+                               if (s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
+                                       goto failed_keep_alive;
                                /* don't let a connection request be initiated */
                                buffer_dont_connect(req);
                                s->rep->flags &= ~BF_EXPECT_MORE; /* speed up sending a previous response */
@@ -4277,6 +4281,8 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
                             rep->r > rep->data + rep->size - global.tune.maxrewrite)) {
                        if (rep->send_max) {
                                /* some data has still not left the buffer, wake us once that's done */
+                               if (rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
+                                       goto abort_response;
                                buffer_dont_close(rep);
                                rep->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
                                return 0;
@@ -4338,7 +4344,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
                                s->srv->counters.failed_resp++;
                                health_adjust(s->srv, HANA_STATUS_HTTP_HDRRSP);
                        }
-
+               abort_response:
                        buffer_auto_close(rep);
                        rep->analysers = 0;
                        txn->status = 502;