From 1a52dbda597768727273b7cea688c714ffd48b93 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 28 Jun 2009 19:37:53 +0200 Subject: [PATCH] [MEDIUM] session: rework buffer analysis to permit permanent analysers It will soon be necessary to support permanent analysers (eg: HTTP in keep-alive mode). We first have to slightly rework the call to the request analysers so that we don't force ->analysers to be 0 before forwarding data. --- src/session.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/session.c b/src/session.c index 32799d6cd6..9ea45e1ba9 100644 --- a/src/session.c +++ b/src/session.c @@ -704,37 +704,47 @@ struct task *process_session(struct task *t) unsigned int flags = s->req->flags; if (s->req->prod->state >= SI_ST_EST) { + unsigned int last_ana = 0; + /* it's up to the analysers to reset write_ena */ buffer_write_ena(s->req); /* We will call all analysers for which a bit is set in * s->req->analysers, following the bit order from LSB * to MSB. The analysers must remove themselves from - * the list when not needed. This while() loop is in - * fact a cleaner if(). + * the list when not needed. Any analyser may return 0 + * to break out of the loop, either because of missing + * data to take a decision, or because it decides to + * kill the session. We loop at least once through each + * analyser, and we may loop again if other analysers + * are added in the middle. */ - while (s->req->analysers) { - if (s->req->analysers & AN_REQ_INSPECT) + while (s->req->analysers & ~last_ana) { + last_ana = s->req->analysers; + + if (s->req->analysers & AN_REQ_INSPECT) { + last_ana |= AN_REQ_INSPECT; if (!tcp_inspect_request(s, s->req)) break; + } - if (s->req->analysers & AN_REQ_HTTP_HDR) + if (s->req->analysers & AN_REQ_HTTP_HDR) { + last_ana |= AN_REQ_HTTP_HDR; if (!http_process_request(s, s->req)) break; + } - if (s->req->analysers & AN_REQ_HTTP_TARPIT) + if (s->req->analysers & AN_REQ_HTTP_TARPIT) { + last_ana |= AN_REQ_HTTP_TARPIT; if (!http_process_tarpit(s, s->req)) break; + } - if (s->req->analysers & AN_REQ_HTTP_BODY) + if (s->req->analysers & AN_REQ_HTTP_BODY) { + last_ana |= AN_REQ_HTTP_BODY; if (!http_process_request_body(s, s->req)) break; - - /* Just make sure that nobody set a wrong flag causing an endless loop */ - s->req->analysers &= AN_REQ_INSPECT | AN_REQ_HTTP_HDR | AN_REQ_HTTP_TARPIT | AN_REQ_HTTP_BODY; - - /* we don't want to loop anyway */ - break; + } } }