]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] process_session: make use of the new buffer flags
authorWilly Tarreau <w@1wt.eu>
Sat, 30 Aug 2008 11:36:43 +0000 (13:36 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Nov 2008 09:19:09 +0000 (10:19 +0100)
Now we have almost two distinct parts between tcp and http.
Only the connection establishment code still requires some
resynchronization, the rest does not.

include/types/buffers.h
src/proto_http.c

index b04daaf430533c707d045e6758fe77da7eb1bc79..7e72c28e1d2c1d496ae95c52464b2357860e4da9 100644 (file)
@@ -93,7 +93,7 @@
 #define BF_MASK_INTERFACE_O     (BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_WRITE_ACTIVITY|BF_WRITE_TIMEOUT|BF_SHUTW_NOW|BF_SHUTR|BF_SHUTW)
 #define BF_MASK_INTERFACE       (BF_MASK_INTF_I | BF_MASK_INTF_O)
 
-#define BF_MASK_ANALYSER        (BF_FULL|BF_READ_ACTIVITY|BF_READ_TIMEOUT|BF_ANA_TIMEOUT|BF_SHUTR|BF_READ_ATTACHED|BF_WRITE_ERROR)
+#define BF_MASK_ANALYSER        (BF_READ_ATTACHED|BF_READ_ACTIVITY|BF_READ_TIMEOUT|BF_ANA_TIMEOUT|BF_WRITE_ACTIVITY)
 #define BF_MASK_HIJACKER        (BF_FULL|BF_WRITE_ACTIVITY|BF_WRITE_TIMEOUT|BF_SHUTW)
 
 
index 31c987977e87b428182b30e2920cb32dcd745318..3eb9e151b1bad22bb229a33897e221dd5d744fe9 100644 (file)
@@ -658,15 +658,19 @@ void process_session(struct task *t, int *next)
        int resync;
        unsigned int rqf_cli, rpf_cli;
        unsigned int rqf_srv, rpf_srv;
-       unsigned int rqf_req, rpf_rep;
 
        /* Check timeouts only during data phase for now */
        if (unlikely(t->state & TASK_WOKEN_TIMER)) {
-               if (s->rep->cons->state == SI_ST_EST)
+               if (s->rep->cons->state == SI_ST_EST) {
                        stream_sock_data_check_timeouts(s->rep->cons->fd);
-
-               if (s->req->cons->state == SI_ST_EST)
+                       if (tick_is_expired(s->rep->analyse_exp, now_ms))
+                               s->rep->flags |= BF_ANA_TIMEOUT;
+               }
+               if (s->req->cons->state == SI_ST_EST) {
                        stream_sock_data_check_timeouts(s->req->cons->fd);
+                       if (tick_is_expired(s->req->analyse_exp, now_ms))
+                               s->req->flags |= BF_ANA_TIMEOUT;
+               }
        }
 
        /* Check if we need to close the write side. This can only happen
@@ -727,8 +731,8 @@ void process_session(struct task *t, int *next)
        }
 
        /* Dirty trick: force one first pass everywhere */
-       rqf_cli = rqf_srv = rqf_req = ~s->req->flags;
-       rpf_cli = rpf_srv = rpf_rep = ~s->rep->flags;
+       rqf_cli = rqf_srv = ~s->req->flags;
+       rpf_cli = rpf_srv = ~s->rep->flags;
 
        /* well, the ST_CONN state is already handled properly */
        if (s->req->prod->state == SI_ST_EST) {
@@ -752,46 +756,10 @@ void process_session(struct task *t, int *next)
 
                resync = 0;
 
-               /* Analyse request */
-               if ((rqf_req ^ s->req->flags) & BF_MASK_ANALYSER) {
-                       if (s->req->prod->state >= SI_ST_EST) {
-                               resync = 1;
-                               /* it's up to the analysers to reset write_ena */
-                               buffer_write_ena(s->req);
-                               if (s->req->analysers)
-                                       process_request(s);
-                               rqf_req = s->req->flags;
-                       }
-
-               }
-
-               /* Analyse response */
-               if (unlikely(s->rep->flags & BF_HIJACK)) {
-                       /* In inject mode, we wake up everytime something has
-                        * happened on the write side of the buffer.
-                        */
-                       if ((s->rep->flags & (BF_WRITE_PARTIAL|BF_WRITE_ERROR|BF_SHUTW)) &&
-                           !(s->rep->flags & BF_FULL)) {
-                               if (produce_content(s) != 0)
-                                       resync = 1; /* completed, better re-check flags */
-                       }
-               }
-               else if (s->rep->prod->state >= SI_ST_EST) {
-                       if ((rpf_rep ^ s->rep->flags) & BF_MASK_ANALYSER) {
-                               resync = 1;
-                               /* it's up to the analysers to reset write_ena */
-                               buffer_write_ena(s->rep);
-                               if (s->rep->analysers)
-                                       process_response(s);
-                               rpf_rep = s->rep->flags;
-                       }
-               }
-
                /* Maybe resync client FD state */
                if (s->rep->cons->state != SI_ST_CLO) {
                        if (((rqf_cli ^ s->req->flags) & BF_MASK_INTERFACE_I) ||
                            ((rpf_cli ^ s->rep->flags) & BF_MASK_INTERFACE_O)) {
-                               resync = 1;
                                stream_sock_data_update(s->rep->cons->fd);
                                rqf_cli = s->req->flags;
                                rpf_cli = s->rep->flags;
@@ -811,10 +779,10 @@ void process_session(struct task *t, int *next)
                if (s->req->cons->state != SI_ST_CLO) {
                        if (((rpf_srv ^ s->rep->flags) & BF_MASK_INTERFACE_I) ||
                            ((rqf_srv ^ s->req->flags) & BF_MASK_INTERFACE_O)) {
-                               resync = 1;
-
-                               if (s->req->cons->state < SI_ST_EST && s->req->flags & BF_WRITE_ENA)
+                               if (s->req->cons->state < SI_ST_EST && s->req->flags & BF_WRITE_ENA) {
                                        process_srv_conn(s);
+                                       resync = 1; /* we might have to resync */
+                               }
 
                                if (s->req->cons->state == SI_ST_EST) {
                                        if ((s->req->flags & (BF_SHUTW|BF_EMPTY|BF_WRITE_ENA)) == (BF_EMPTY|BF_WRITE_ENA) &&
@@ -855,6 +823,66 @@ void process_session(struct task *t, int *next)
                        }
                }
 
+               /* we may have to resync because of pending connections */
+               if (resync)
+                       continue;
+
+               /**** Process layer 7 below ****/
+
+               /* Analyse request */
+               if (s->req->flags & BF_MASK_ANALYSER) {
+                       unsigned int flags = s->req->flags;
+
+                       if (s->req->prod->state >= SI_ST_EST) {
+                               /* it's up to the analysers to reset write_ena */
+                               buffer_write_ena(s->req);
+                               if (s->req->analysers)
+                                       process_request(s);
+                       }
+                       s->req->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+                       flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+                       if (s->req->flags != flags)
+                               resync = 1;
+               }
+
+               /* Analyse response */
+               if (unlikely(s->rep->flags & BF_HIJACK)) {
+                       /* In inject mode, we wake up everytime something has
+                        * happened on the write side of the buffer.
+                        */
+                       unsigned int flags = s->rep->flags;
+
+                       if ((s->rep->flags & (BF_WRITE_PARTIAL|BF_WRITE_ERROR|BF_SHUTW)) &&
+                           !(s->rep->flags & BF_FULL)) {
+                               produce_content(s);
+                       }
+                       s->rep->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+                       flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+                       if (s->rep->flags != flags)
+                               resync = 1;
+               }
+               else if (s->rep->flags & BF_MASK_ANALYSER) {
+                       unsigned int flags = s->rep->flags;
+
+                       if (s->rep->prod->state >= SI_ST_EST) {
+                               /* it's up to the analysers to reset write_ena */
+                               buffer_write_ena(s->rep);
+                               if (s->rep->analysers)
+                                       process_response(s);
+                       }
+                       s->rep->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+                       flags &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+                       if (s->rep->flags != flags)
+                               resync = 1;
+               }
+
+               /* For the moment, we need to clean the client and server flags that
+                * have vanished. This is just a temporary measure though.
+                */
+               rqf_cli &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+               rqf_srv &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+               rpf_cli &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
+               rpf_srv &= BF_CLEAR_READ & BF_CLEAR_WRITE & BF_CLEAR_TIMEOUT;
        } while (resync);
 
        if (likely((s->rep->cons->state != SI_ST_CLO) ||