package: haproxy
[openwrt/svn-archive/archive.git] / net / haproxy / patches / 0016-BUG-MINOR-http-don-t-report-client-aborts-as-s-1.4.22.diff
1 From 46169a35f95f2128bbf185c06eb535d9acb7ee61 Mon Sep 17 00:00:00 2001
2 From: Willy Tarreau <w@1wt.eu>
3 Date: Mon, 26 Nov 2012 13:35:37 +0100
4 Subject: BUG/MINOR: http: don't report client aborts as server errors
5
6 If a client aborts with an abortonclose flag, the close is forwarded
7 to the server and when server response is processed, the analyser thinks
8 it's the server who has closed first, and logs flags "SD" or "SH" and
9 counts a server error. In order to avoid this, we now first detect that
10 the client has closed and log a client abort instead.
11
12 This likely is the reason why many people have been observing a small rate
13 of SD/SH flags without being able to find what the error was.
14
15 This fix should probably be backported to 1.4.
16 (cherry picked from commit f003d375ec5190e7d99cfa14a9b09e7ca6c55daf)
17 ---
18 src/proto_http.c | 37 +++++++++++++++++++++++++++++++++----
19 1 files changed, 33 insertions(+), 4 deletions(-)
20
21 diff --git a/src/proto_http.c b/src/proto_http.c
22 index 1ad838b..ae37035 100644
23 --- a/src/proto_http.c
24 +++ b/src/proto_http.c
25 @@ -4919,6 +4919,28 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
26 return 0;
27 }
28
29 + /* client abort with an abortonclose */
30 + else if ((rep->flags & BF_SHUTR) && ((s->req->flags & (BF_SHUTR|BF_SHUTW)) == (BF_SHUTR|BF_SHUTW))) {
31 + s->fe->counters.cli_aborts++;
32 + if (s->fe != s->be)
33 + s->be->counters.cli_aborts++;
34 + if (s->srv)
35 + s->srv->counters.cli_aborts++;
36 +
37 + buffer_auto_close(rep);
38 + rep->analysers = 0;
39 + txn->status = 400;
40 + buffer_ignore(rep, rep->l - rep->send_max);
41 + stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_400));
42 +
43 + if (!(s->flags & SN_ERR_MASK))
44 + s->flags |= SN_ERR_CLICL;
45 + if (!(s->flags & SN_FINST_MASK))
46 + s->flags |= SN_FINST_H;
47 + /* process_session() will take care of the error */
48 + return 0;
49 + }
50 +
51 /* close from server, capture the response if the server has started to respond */
52 else if (rep->flags & BF_SHUTR) {
53 if (msg->msg_state >= HTTP_MSG_RPVER || msg->err_pos >= 0)
54 @@ -5666,8 +5688,18 @@ int http_response_forward_body(struct session *s, struct buffer *res, int an_bit
55 }
56
57 missing_data:
58 - /* stop waiting for data if the input is closed before the end */
59 +
60 + if (res->flags & BF_SHUTW)
61 + goto aborted_xfer;
62 +
63 + /* stop waiting for data if the input is closed before the end. If the
64 + * client side was already closed, it means that the client has aborted,
65 + * so we don't want to count this as a server abort. Otherwise it's a
66 + * server abort.
67 + */
68 if (res->flags & BF_SHUTR) {
69 + if ((res->flags & BF_SHUTW_NOW) || (s->req->flags & BF_SHUTR))
70 + goto aborted_xfer;
71 if (!(s->flags & SN_ERR_MASK))
72 s->flags |= SN_ERR_SRVCL;
73 s->be->counters.srv_aborts++;
74 @@ -5676,9 +5708,6 @@ int http_response_forward_body(struct session *s, struct buffer *res, int an_bit
75 goto return_bad_res_stats_ok;
76 }
77
78 - if (res->flags & BF_SHUTW)
79 - goto aborted_xfer;
80 -
81 /* we need to obey the req analyser, so if it leaves, we must too */
82 if (!s->req->analysers)
83 goto return_bad_res;
84 --
85 1.7.1
86