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
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.
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.
15 This fix should probably be backported to 1.4.
16 (cherry picked from commit f003d375ec5190e7d99cfa14a9b09e7ca6c55daf)
18 src/proto_http.c | 37 +++++++++++++++++++++++++++++++++----
19 1 files changed, 33 insertions(+), 4 deletions(-)
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)
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++;
33 + s->be->counters.cli_aborts++;
35 + s->srv->counters.cli_aborts++;
37 + buffer_auto_close(rep);
40 + buffer_ignore(rep, rep->l - rep->send_max);
41 + stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_400));
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 */
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
58 - /* stop waiting for data if the input is closed before the end */
60 + if (res->flags & BF_SHUTW)
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
68 if (res->flags & BF_SHUTR) {
69 + if ((res->flags & BF_SHUTW_NOW) || (s->req->flags & BF_SHUTR))
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;
78 - if (res->flags & BF_SHUTW)
81 /* we need to obey the req analyser, so if it leaves, we must too */
82 if (!s->req->analysers)