From: Willy Tarreau Date: Fri, 28 Dec 2012 07:36:50 +0000 (+0100) Subject: BUG/MEDIUM: stats: disable request analyser when processing POST or HEAD X-Git-Tag: v1.5-dev17~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbc743e36cf593e9e4c3fd140dd7b3c720ddbdf1;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: stats: disable request analyser when processing POST or HEAD After the response headers are sent and the request processing is done, the buffers are wiped out and the stream interface is closed. We must then disable the request analysers, otherwise some processing will happen on a closed stream interface and empty buffers which do not match, causing all sort of crashes. This issue was introduced with recent work on the stats, and was reported by Seri. --- diff --git a/src/proto_http.c b/src/proto_http.c index 3b5a478a20..69ef88136f 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -2929,7 +2929,8 @@ int http_process_req_stat_post(struct stream_interface *si, struct http_txn *txn /* This function checks whether we need to enable a POST analyser to parse a * stats request, and also registers the stats I/O handler. It returns zero - * if it needs to come back again, otherwise non-zero if it finishes. + * if it needs to come back again, otherwise non-zero if it finishes. In the + * latter case, it also clears the request analysers. */ int http_handle_stats(struct session *s, struct channel *req) { @@ -3012,6 +3013,7 @@ int http_handle_stats(struct session *s, struct channel *req) s->flags |= SN_ERR_PRXCOND; // to mark that it comes from the proxy if (!(s->flags & SN_FINST_MASK)) s->flags |= SN_FINST_R; + req->analysers = 0; return 1; } @@ -3045,6 +3047,7 @@ int http_handle_stats(struct session *s, struct channel *req) /* that's all we return in case of HEAD request, so let's immediately close. */ stream_int_retnclose(req->prod, &trash); s->target = &http_stats_applet.obj_type; /* just for logging the applet name */ + req->analysers = 0; return 1; } @@ -3057,7 +3060,6 @@ int http_handle_stats(struct session *s, struct channel *req) s->rep->prod->conn->xprt_ctx = s; s->rep->prod->applet.st0 = s->rep->prod->applet.st1 = 0; req->analysers = 0; - return 1; }