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);
* 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)
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 = {{ },{
ret = !ret;
if (ret) {
- session_set_backend(s, rule->be.backend);
+ if (!session_set_backend(s, rule->be.backend))
+ goto sw_failed;
break;
}
}
* 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 */
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,