extern struct si_ops si_conn_ops;
extern struct data_cb si_conn_cb;
-struct task *stream_int_register_handler(struct stream_interface *si,
- struct si_applet *app);
+struct appctx *stream_int_register_handler(struct stream_interface *si, struct si_applet *app);
void stream_int_unregister_handler(struct stream_interface *si);
/* initializes a stream interface in the SI_ST_INI state. It's detached from
struct appctx *appctx;
s->target = &cli_applet.obj_type;
- stream_int_register_handler(&s->si[1], objt_applet(s->target));
- appctx = si_appctx(&s->si[1]);
+ appctx = stream_int_register_handler(&s->si[1], objt_applet(s->target));
+ if (!appctx)
+ return -1;
appctx->st1 = 0;
appctx->st0 = STAT_CLI_INIT;
struct appctx *appctx;
s->target = &peer_applet.obj_type;
- stream_int_register_handler(&s->si[1], objt_applet(s->target));
- appctx = si_appctx(&s->si[1]);
+ appctx = stream_int_register_handler(&s->si[1], objt_applet(s->target));
+ if (!appctx)
+ return -1;
appctx->st0 = PEER_SESSION_ACCEPT;
appctx->ctx.peers.ptr = s;
if (s->fe->options2 & PR_O2_INDEPSTR)
s->si[0].flags |= SI_FL_INDEP_STR;
- stream_int_register_handler(&s->si[0], &peer_applet);
- appctx = si_appctx(&s->si[0]);
+ appctx = stream_int_register_handler(&s->si[0], &peer_applet);
+ if (!appctx)
+ goto out_fail_conn1;
appctx->st0 = PEER_SESSION_CONNECT;
appctx->ctx.peers.ptr = (void *)ps;
if (!http_req_last_rule) {
if (stats_check_uri(s->rep->prod, txn, px)) {
s->target = &http_stats_applet.obj_type;
- stream_int_register_handler(s->rep->prod, objt_applet(s->target));
+ if (unlikely(!stream_int_register_handler(s->rep->prod, objt_applet(s->target)))) {
+ txn->status = 500;
+ s->logs.tv_request = now;
+ stream_int_retnclose(req->prod, http_error_message(s, HTTP_ERR_500));
+ if (!(s->flags & SN_ERR_MASK))
+ s->flags |= SN_ERR_RESOURCE;
+ goto return_prx_cond;
+ }
/* parse the whole stats request and extract the relevant information */
http_handle_stats(s, req);
http_req_last_rule = http_req_get_intercept_rule(px, &px->uri_auth->http_req_rules, s, txn);
task_wakeup(si->owner, TASK_WOKEN_IO);
}
-/* Register an applet to handle a stream_interface as part of the stream
- * interface's owner task, which is returned. The SI will wake it up everytime
- * it is solicited. The task's processing function must call the applet's
- * function before returning. It must be deleted by the task handler using
- * stream_int_unregister_handler(), possibly from within the function itself.
- * It also pre-initializes applet.state to zero and the connection context
- * to NULL.
+/* Register an applet to handle a stream_interface as part of the
+ * stream interface's owner task. The SI will wake it up everytime it
+ * is solicited. The task's processing function must call the applet's
+ * function before returning. It must be deleted by the task handler
+ * using stream_int_unregister_handler(), possibly from within the
+ * function itself. It also pre-initializes the applet's context and
+ * returns it (or NULL in case it could not be allocated).
*/
-struct task *stream_int_register_handler(struct stream_interface *si, struct si_applet *app)
+struct appctx *stream_int_register_handler(struct stream_interface *si, struct si_applet *app)
{
DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", app, si, si->owner);
si_attach_applet(si, app);
si->flags |= SI_FL_WAIT_DATA;
- return si->owner;
+ return si_appctx(si);
}
/* Unregister a stream interface handler. This must be called by the handler task