Modules: expose real client on conn events.

When REDISMODULE_EVENT_CLIENT_CHANGE events are delivered, modules may
want to mutate the client state (e.g. perform authentication).

This change links the module context with the real client rather than a
fake client for these events.

(cherry picked from commit 67b43f75e2)
This commit is contained in:
Yossi Gottlieb 2020-08-18 17:16:08 +03:00 committed by Oran Agra
parent e83d6b0cfa
commit 919580a228

View File

@ -7263,6 +7263,7 @@ void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
* cheap if there are no registered modules. */
if (listLength(RedisModule_EventListeners) == 0) return;
int real_client_used = 0;
listIter li;
listNode *ln;
listRewind(RedisModule_EventListeners,&li);
@ -7272,7 +7273,15 @@ void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
ctx.module = el->module;
if (ModulesInHooks == 0) {
if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) {
/* In the case of client changes, we're pushing the real client
* so the event handler can mutate it if needed. For example,
* to change its authentication state in a way that does not
* depend on specific commands executed later.
*/
ctx.client = (client *) data;
real_client_used = 1;
} else if (ModulesInHooks == 0) {
ctx.client = moduleFreeContextReusedClient;
} else {
ctx.client = createClient(NULL);
@ -7325,7 +7334,7 @@ void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
el->module->in_hook--;
ModulesInHooks--;
if (ModulesInHooks != 0) freeClient(ctx.client);
if (ModulesInHooks != 0 && !real_client_used) freeClient(ctx.client);
moduleFreeContext(&ctx);
}
}