TEST_F(TestIronBeeModuleRulesLua, new_state)
{
    int res = 0;
    ib_tx_t tx;
    tx.ib = ib_engine;

    ib_rule_exec_t rule_exec;
    memset(&rule_exec, 0, sizeof(rule_exec));
    rule_exec.ib = ib_engine;
    rule_exec.tx = &tx;
    rule_exec.rule = rule;

    ib_tx_generate_id(&tx, ib_engine->mp);
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    setSearchPath(L);
    ASSERT_EQ(IB_OK, ib_lua_require(ib_engine, L, "ffi", "ffi"));
    ASSERT_EQ(IB_OK, ib_lua_require(ib_engine, L, "ibapi", "ironbee/api"));
    ASSERT_NE(static_cast<lua_State*>(NULL), L);

    lua_State *L2;

    ASSERT_EQ(IB_OK, ib_lua_new_thread(ib_engine, L, &L2));
    ASSERT_NE(static_cast<lua_State*>(NULL), L2);
    ASSERT_EQ(IB_OK, ib_lua_load_func(ib_engine, L2, luafile, "f1"));
    ASSERT_EQ(IB_OK, ib_lua_func_eval_int(ib_engine, &tx, L2, "f1", &res));
    ASSERT_EQ(IB_OK, ib_lua_join_thread(ib_engine, L, &L2));
    ASSERT_EQ(5, res);
}
TEST_F(TestIronBeeModuleRulesLua, load_func_eval)
{
    int res = 0;
    ib_tx_t tx;
    tx.ib = ib_engine;
    tx.id = "tx_id.TestIronBeeModuleRulesLua.load_func_eval";
    ASSERT_EQ(IB_OK, ib_conn_create(ib_engine, &tx.conn, NULL));

    ib_rule_exec_t rule_exec;
    memset(&rule_exec, 0, sizeof(rule_exec));
    rule_exec.ib = ib_engine;
    rule_exec.tx = &tx;
    rule_exec.rule = rule;

    lua_State *L = luaL_newstate();
    ASSERT_NE(static_cast<lua_State*>(NULL), L);
    luaL_openlibs(L);
    setSearchPath(L);
    ASSERT_EQ(IB_OK, ib_lua_require(ib_engine, L, "ffi", "ffi"));
    ASSERT_EQ(IB_OK, ib_lua_require(ib_engine, L, "ibapi", "ironbee/api"));
    ASSERT_EQ(IB_OK, ib_lua_load_func(ib_engine, L, luafile, "f1"));
    ASSERT_EQ(IB_OK, ib_lua_func_eval_int(ib_engine, &tx, L, "f1", &res));
    ASSERT_EQ(5, res);
}
Beispiel #3
0
/**
 * Called by RuleExt lua:.
 *
 * @param[in] cp       Configuration parser.
 * @param[in] rule     Rule under construction.
 * @param[in] tag      Should be "lua".
 * @param[in] location What comes after "lua:".
 * @param[in] cbdata   Callback data; unused.
 * @return
 * - IB_OK on success.
 * - IB_EINVAL if Lua not available or not called for "lua" tag.
 * - Other error code if loading or registration fails.
 */
static ib_status_t modlua_rule_driver(
    ib_cfgparser_t *cp,
    ib_rule_t *rule,
    const char *tag,
    const char *location,
    void *cbdata
)
{
    assert(cp != NULL);
    assert(cp->ib != NULL);
    assert(tag != NULL);
    assert(location != NULL);

    ib_status_t            rc;
    const char            *slash;
    const char            *name;
    ib_operator_t         *op;
    ib_operator_inst_t    *opinst;
    ib_engine_t           *ib                 = cp->ib;
    modlua_cfg_t          *cfg                = NULL;
    ib_context_t          *ctx                = NULL;
    modlua_rules_cbdata_t *modlua_rules_cbdata =
        (modlua_rules_cbdata_t *)cbdata;

    /* This cbdata is passed on to the implementation. Validate it here. */
    assert(modlua_rules_cbdata != NULL);
    assert(modlua_rules_cbdata->module != NULL);

    if (strncmp(tag, "lua", 3) != 0) {
        ib_cfg_log_error(cp, "Lua rule driver called for non-lua tag.");
        return IB_EINVAL;
    }

    rc = ib_cfgparser_context_current(cp, &ctx);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to retrieve current context.");
        return rc;
    }

    rc = modlua_cfg_get(ib, ctx, &cfg);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_lua_load_func(
        cp->ib,
        cfg->L,
        location,
        ib_rule_id(rule));
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to load lua file \"%s\"", location);
        return rc;
    }

    /* Record that we need to reload this rule in each TX. */
    rc = modlua_record_reload(
        cp->ib,
        cfg,
        MODLUA_RELOAD_RULE,
        NULL,
        ib_rule_id(rule),
        location);
    if (rc != IB_OK) {
        ib_cfg_log_error(
            cp,
            "Failed to record lua file \"%s\" to reload",
            location);
        return rc;
    }

    slash = strrchr(location, '/');
    if (slash == NULL) {
        name = location;
    }
    else {
        name = slash + 1;
    }

    rc = ib_operator_create_and_register(
        &op,
        cp->ib,
        name,
        IB_OP_CAPABILITY_NONE,
        &lua_operator_create,
        modlua_rules_cbdata,
        NULL,
        NULL,
        &lua_operator_execute,
        modlua_rules_cbdata
    );
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Error registering lua operator \"%s\": %s",
                         name, ib_status_to_string(rc));
        return rc;
    }

    rc = ib_operator_inst_create(&opinst,
                                 ib_engine_mm_main_get(cp->ib),
                                 ctx,
                                 op,
                                 ib_rule_required_op_flags(rule),
                                 ib_rule_id(rule)); /* becomes instance_data */

    if (rc != IB_OK) {
        ib_cfg_log_error(cp,
                         "Error instantiating lua operator "
                         "for rule \"%s\": %s",
                         name, ib_status_to_string(rc));
        return rc;
    }

    rc = ib_rule_set_operator(cp->ib, rule, opinst);

    if (rc != IB_OK) {
        ib_cfg_log_error(cp,
                         "Error associating lua operator \"%s\" "
                         "with rule \"%s\": %s",
                         name, ib_rule_id(rule), ib_status_to_string(rc));
        return rc;
    }

    return IB_OK;
}