enum act_opt {
ACT_OPT_NONE = 0x00000000, /* no flag */
ACT_OPT_FINAL = 0x00000001, /* last call, cannot yield */
- ACT_OPT_FIRST = 0x00000002, /* first call for this action */
+ ACT_OPT_FINAL_EARLY = 0x00000002, /* set in addition to ACT_OPT_FINAL if last call occurs earlier than normal due to unexpected IO/error */
+ ACT_OPT_FIRST = 0x00000004, /* first call for this action */
};
/* Flags used to describe the action. */
case HLUA_E_YIELD:
err_yield:
act_ret = ACT_RET_CONT;
- SEND_ERR(px, "Lua function '%s': yield not allowed.\n",
- rule->arg.hlua_rule->fcn->name);
+ if (flags & ACT_OPT_FINAL_EARLY) {
+ char *msg = NULL;
+
+ /* yield not allowed, but it is only caused because ruleset was ended earlier
+ * than expected, so it is not a misuse of yield in the Lua script: simply emit
+ * a log
+ */
+ memprintf(&msg, "Lua function '%s': unable to yield, aborted Lua execution.\n",
+ rule->arg.hlua_rule->fcn->name);
+ if (msg)
+ hlua_sendlog(px, LOG_WARNING, msg);
+ ha_free(&msg);
+ }
+ else {
+ /* invalid yield use */
+ SEND_ERR(px, "Lua function '%s': yield not allowed.\n",
+ rule->arg.hlua_rule->fcn->name);
+ }
goto end;
case HLUA_E_ERR:
if ((s->scf->flags & SC_FL_ERROR) ||
((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
(px->options & PR_O_ABRT_CLOSE)))
- act_opts |= ACT_OPT_FINAL;
+ act_opts |= ACT_OPT_FINAL | ACT_OPT_FINAL_EARLY;
/* If "the current_rule_list" match the executed rule list, we are in
* resume condition. If a resume is needed it is always in the action
if ((s->scf->flags & SC_FL_ERROR) ||
((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
(px->options & PR_O_ABRT_CLOSE)))
- act_opts |= ACT_OPT_FINAL;
+ act_opts |= ACT_OPT_FINAL | ACT_OPT_FINAL_EARLY;
/* If "the current_rule_list" match the executed rule list, we are in
* resume condition. If a resume is needed it is always in the action
partial = SMP_OPT_FINAL;
/* Action may yield while the inspect_delay is not expired and there is no read error */
if ((s->scf->flags & SC_FL_ERROR) || !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
- act_opts |= ACT_OPT_FINAL;
+ act_opts |= ACT_OPT_FINAL | ACT_OPT_FINAL_EARLY;
}
else
partial = 0;
partial = SMP_OPT_FINAL;
/* Action may yield while the inspect_delay is not expired and there is no read error */
if ((s->scb->flags & SC_FL_ERROR) || !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
- act_opts |= ACT_OPT_FINAL;
+ act_opts |= ACT_OPT_FINAL | ACT_OPT_FINAL_EARLY;
}
else
partial = 0;