diff --git a/src/modules/hellofilter.c b/src/modules/hellofilter.c index 84eb02c3..d5dd405a 100644 --- a/src/modules/hellofilter.c +++ b/src/modules/hellofilter.c @@ -6,17 +6,32 @@ static RedisModuleString *log_key_name; static const char log_command_name[] = "hellofilter.log"; +static const char ping_command_name[] = "hellofilter.ping"; +static int in_module = 0; + +int HelloFilter_PingCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) +{ + RedisModuleCallReply *reply = RedisModule_Call(ctx, "ping", "c", "@log"); + if (reply) { + RedisModule_ReplyWithCallReply(ctx, reply); + RedisModule_FreeCallReply(reply); + } else { + RedisModule_ReplyWithSimpleString(ctx, "Unknown command or invalid arguments"); + } + + return REDISMODULE_OK; +} int HelloFilter_LogCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { - RedisModuleString *s = RedisModule_CreateStringFromString(ctx, argv[0]); + RedisModuleString *s = RedisModule_CreateString(ctx, "", 0); int i; for (i = 1; i < argc; i++) { size_t arglen; const char *arg = RedisModule_StringPtrLen(argv[i], &arglen); - RedisModule_StringAppendBuffer(ctx, s, " ", 1); + if (i > 1) RedisModule_StringAppendBuffer(ctx, s, " ", 1); RedisModule_StringAppendBuffer(ctx, s, arg, arglen); } @@ -25,6 +40,8 @@ int HelloFilter_LogCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int ar RedisModule_CloseKey(log); RedisModule_FreeString(ctx, s); + in_module = 1; + size_t cmdlen; const char *cmdname = RedisModule_StringPtrLen(argv[1], &cmdlen); RedisModuleCallReply *reply = RedisModule_Call(ctx, cmdname, "v", &argv[2], argc - 2); @@ -34,12 +51,15 @@ int HelloFilter_LogCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int ar } else { RedisModule_ReplyWithSimpleString(ctx, "Unknown command or invalid arguments"); } + + in_module = 0; + return REDISMODULE_OK; } -void HelloFilter_CommandFilter(RedisModuleCtx *ctx, RedisModuleCommandFilterCtx *filter) +void HelloFilter_CommandFilter(RedisModuleCommandFilterCtx *filter) { - (void) ctx; + if (in_module) return; /* don't process our own RM_Call() */ /* Fun manipulations: * - Remove @delme @@ -94,6 +114,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) HelloFilter_LogCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR) return REDISMODULE_ERR; + if (RedisModule_CreateCommand(ctx,ping_command_name, + HelloFilter_PingCommand,"write deny-oom",1,1,1) == REDISMODULE_ERR) + return REDISMODULE_ERR; + if (RedisModule_RegisterCommandFilter(ctx, HelloFilter_CommandFilter) == REDISMODULE_ERR) return REDISMODULE_ERR; diff --git a/tests/modules/commandfilter.tcl b/tests/modules/commandfilter.tcl index f0d96b25..47d9c302 100644 --- a/tests/modules/commandfilter.tcl +++ b/tests/modules/commandfilter.tcl @@ -6,7 +6,7 @@ start_server {tags {"modules"}} { test {Command Filter handles redirected commands} { r set mykey @log r lrange log-key 0 -1 - } "{hellofilter.log set mykey @log}" + } "{set mykey @log}" test {Command Filter can call RedisModule_CommandFilterArgDelete} { r rpush mylist elem1 @delme elem2 @@ -24,4 +24,22 @@ start_server {tags {"modules"}} { r rpush mylist elem1 @replaceme elem2 r lrange mylist 0 -1 } {elem1 --replaced-- elem2} + + test {Command Filter applies on RM_Call() commands} { + r del log-key + r hellofilter.ping + r lrange log-key 0 -1 + } "{ping @log}" + + test {Command Filter applies on Lua redis.call()} { + r del log-key + r eval "redis.call('ping', '@log')" 0 + r lrange log-key 0 -1 + } "{ping @log}" + + test {Command Filter applies on Lua redis.call() that calls a module} { + r del log-key + r eval "redis.call('hellofilter.ping')" 0 + r lrange log-key 0 -1 + } "{ping @log}" }