]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] prepare callers of session_set_backend to handle errors
authorWilly Tarreau <w@1wt.eu>
Sun, 12 Jul 2009 06:27:39 +0000 (08:27 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 12 Jul 2009 06:36:24 +0000 (08:36 +0200)
session_set_backend will soon have to allocate areas for HTTP
headers. We must ensure that the callers can handle an allocation
error.

include/proto/proxy.h
src/proxy.c
src/session.c

index 36360e5cf5bf718dd47c05cbf30fe7f64676c11b..0ad1e7fe8bf83d205fe2da7bdd7817fd1ab8114d 100644 (file)
@@ -35,7 +35,7 @@ void pause_proxy(struct proxy *p);
 void stop_proxy(struct proxy *p);
 void pause_proxies(void);
 void listen_proxies(void);
-void session_set_backend(struct session *s, struct proxy *be);
+int  session_set_backend(struct session *s, struct proxy *be);
 
 const char *proxy_cap_str(int cap);
 const char *proxy_mode_str(int mode);
index dcfb12d879e1a5608ad7123639d866e0ca80fdf2..2dfc93b3b17d6c72ff929372fff25a2b9915a08d 100644 (file)
@@ -635,11 +635,12 @@ void listen_proxies(void)
  * session already had a backend assigned, which is indicated by
  * s->flags & SN_BE_ASSIGNED.
  * All flags, stats and counters which need be updated are updated.
+ * Returns 1 if done, 0 in case of internal error, eg: lack of resource.
  */
-void session_set_backend(struct session *s, struct proxy *be)
+int session_set_backend(struct session *s, struct proxy *be)
 {
        if (s->flags & SN_BE_ASSIGNED)
-               return;
+               return 1;
        s->be = be;
        be->beconn++;
        if (be->beconn > be->beconn_max)
@@ -653,6 +654,7 @@ void session_set_backend(struct session *s, struct proxy *be)
        if (be->options2 & PR_O2_RSPBUG_OK)
                s->txn.rsp.err_pos = -1; /* let buggy responses pass */
        s->flags |= SN_BE_ASSIGNED;
+       return 1;
 }
 
 static struct cfg_kw_list cfg_kws = {{ },{
index d4817ac2c380fe95d080278bddd8458c106ca548..7d95669fb4df22bc6cdb0b8cc1038d7eabbc86e3 100644 (file)
@@ -586,7 +586,8 @@ int process_switching_rules(struct session *s, struct buffer *req, int an_bit)
                                ret = !ret;
 
                        if (ret) {
-                               session_set_backend(s, rule->be.backend);
+                               if (!session_set_backend(s, rule->be.backend))
+                                       goto sw_failed;
                                break;
                        }
                }
@@ -597,7 +598,8 @@ int process_switching_rules(struct session *s, struct buffer *req, int an_bit)
                 * backend if any.
                 */
                if (!(s->flags & SN_BE_ASSIGNED))
-                       session_set_backend(s, s->fe->defbe.be ? s->fe->defbe.be : s->be);
+                       if (!session_set_backend(s, s->fe->defbe.be ? s->fe->defbe.be : s->be))
+                               goto sw_failed;
        }
 
        /* we don't want to run the HTTP filters again if the backend has not changed */
@@ -605,6 +607,21 @@ int process_switching_rules(struct session *s, struct buffer *req, int an_bit)
                s->req->analysers &= ~AN_REQ_HTTP_PROCESS_BE;
 
        return 1;
+
+ sw_failed:
+       /* immediately abort this request in case of allocation failure */
+       buffer_abort(s->req);
+       buffer_abort(s->rep);
+
+       if (!(s->flags & SN_ERR_MASK))
+               s->flags |= SN_ERR_RESOURCE;
+       if (!(s->flags & SN_FINST_MASK))
+               s->flags |= SN_FINST_R;
+
+       s->txn.status = 500;
+       s->req->analysers = 0;
+       s->req->analyse_exp = TICK_ETERNITY;
+       return 0;
 }
 
 /* Processes the client, server, request and response jobs of a session task,