Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
dc5edc7b
Commit
dc5edc7b
authored
Mar 18, 2019
by
Yossi Gottlieb
Committed by
antirez
May 13, 2019
Browse files
Add command filtering argument handling API.
parent
5f29e2e2
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/module.c
View file @
dc5edc7b
...
@@ -291,6 +291,10 @@ typedef struct RedisModuleCommandFilter {
...
@@ -291,6 +291,10 @@ typedef struct RedisModuleCommandFilter {
/* Registered filters */
/* Registered filters */
static
list
*
moduleCommandFilters
;
static
list
*
moduleCommandFilters
;
typedef
struct
RedisModuleCommandFilterCtx
{
RedisModuleString
**
argv
;
int
argc
;
}
RedisModuleCommandFilterCtx
;
/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------
* Prototypes
* Prototypes
...
@@ -4844,6 +4848,78 @@ void moduleCallCommandFilters(client *c) {
...
@@ -4844,6 +4848,78 @@ void moduleCallCommandFilters(client *c) {
c
->
argc
=
cmd
.
argc
;
c
->
argc
=
cmd
.
argc
;
}
}
/* Return the number of arguments a filtered command has. The number of
* arguments include the command itself.
*/
int
RM_CommandFilterArgsCount
(
RedisModuleCommandFilterCtx
*
filter
)
{
return
filter
->
argc
;
}
/* Return the specified command argument. The first argument (position 0) is
* the command itself, and the rest are user-provided args.
*/
const
RedisModuleString
*
RM_CommandFilterArgGet
(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
)
{
if
(
pos
<
0
||
pos
>=
filter
->
argc
)
return
NULL
;
return
filter
->
argv
[
pos
];
}
/* Modify the filtered command by inserting a new argument at the specified
* position. The specified RedisModuleString argument may be used by Redis
* after the filter context is destroyed, so it must not be auto-memory
* allocated, freed or used elsewhere.
*/
int
RM_CommandFilterArgInsert
(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
,
RedisModuleString
*
arg
)
{
int
i
;
if
(
pos
<
0
||
pos
>
filter
->
argc
)
return
REDISMODULE_ERR
;
filter
->
argv
=
zrealloc
(
filter
->
argv
,
(
filter
->
argc
+
1
)
*
sizeof
(
RedisModuleString
*
));
for
(
i
=
filter
->
argc
;
i
>
pos
;
i
--
)
{
filter
->
argv
[
i
]
=
filter
->
argv
[
i
-
1
];
}
filter
->
argv
[
pos
]
=
arg
;
filter
->
argc
++
;
return
REDISMODULE_OK
;
}
/* Modify the filtered command by replacing an existing argument with a new one.
* The specified RedisModuleString argument may be used by Redis after the
* filter context is destroyed, so it must not be auto-memory allocated, freed
* or used elsewhere.
*/
int
RM_CommandFilterArgReplace
(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
,
RedisModuleString
*
arg
)
{
if
(
pos
<
0
||
pos
>=
filter
->
argc
)
return
REDISMODULE_ERR
;
decrRefCount
(
filter
->
argv
[
pos
]);
filter
->
argv
[
pos
]
=
arg
;
return
REDISMODULE_OK
;
}
/* Modify the filtered command by deleting an argument at the specified
* position.
*/
int
RM_CommandFilterArgDelete
(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
)
{
int
i
;
if
(
pos
<
0
||
pos
>=
filter
->
argc
)
return
REDISMODULE_ERR
;
decrRefCount
(
filter
->
argv
[
pos
]);
for
(
i
=
pos
;
i
<
filter
->
argc
-
1
;
i
++
)
{
filter
->
argv
[
i
]
=
filter
->
argv
[
i
+
1
];
}
filter
->
argc
--
;
return
REDISMODULE_OK
;
}
/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------
* Modules API internals
* Modules API internals
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
...
@@ -5291,4 +5367,9 @@ void moduleRegisterCoreAPI(void) {
...
@@ -5291,4 +5367,9 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API
(
ExportSharedAPI
);
REGISTER_API
(
ExportSharedAPI
);
REGISTER_API
(
GetSharedAPI
);
REGISTER_API
(
GetSharedAPI
);
REGISTER_API
(
RegisterCommandFilter
);
REGISTER_API
(
RegisterCommandFilter
);
REGISTER_API
(
CommandFilterArgsCount
);
REGISTER_API
(
CommandFilterArgGet
);
REGISTER_API
(
CommandFilterArgInsert
);
REGISTER_API
(
CommandFilterArgReplace
);
REGISTER_API
(
CommandFilterArgDelete
);
}
}
src/modules/hellofilter.c
View file @
dc5edc7b
#define REDISMODULE_EXPERIMENTAL_API
#define REDISMODULE_EXPERIMENTAL_API
#include "../redismodule.h"
#include "../redismodule.h"
#include <string.h>
static
RedisModuleString
*
log_key_name
;
static
RedisModuleString
*
log_key_name
;
static
const
char
log_command_name
[]
=
"hellofilter.log"
;
static
const
char
log_command_name
[]
=
"hellofilter.log"
;
...
@@ -35,16 +37,46 @@ int HelloFilter_LogCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int ar
...
@@ -35,16 +37,46 @@ int HelloFilter_LogCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int ar
return
REDISMODULE_OK
;
return
REDISMODULE_OK
;
}
}
void
HelloFilter_CommandFilter
(
RedisModuleCtx
*
ctx
,
RedisModule
FilteredCommand
*
cmd
)
void
HelloFilter_CommandFilter
(
RedisModuleCtx
*
ctx
,
RedisModule
CommandFilterCtx
*
filter
)
{
{
cmd
->
argv
=
RedisModule_Realloc
(
cmd
->
argv
,
(
cmd
->
argc
+
1
)
*
sizeof
(
RedisModuleString
*
));
(
void
)
ctx
;
int
i
;
for
(
i
=
cmd
->
argc
;
i
>
0
;
i
--
)
{
/* Fun manipulations:
cmd
->
argv
[
i
]
=
cmd
->
argv
[
i
-
1
];
* - Remove @delme
* - Replace @replaceme
* - Append @insertbefore or @insertafter
* - Prefix with Log command if @log encounterd
*/
int
log
=
0
;
int
pos
=
0
;
while
(
pos
<
RedisModule_CommandFilterArgsCount
(
filter
))
{
const
RedisModuleString
*
arg
=
RedisModule_CommandFilterArgGet
(
filter
,
pos
);
size_t
arg_len
;
const
char
*
arg_str
=
RedisModule_StringPtrLen
(
arg
,
&
arg_len
);
if
(
arg_len
==
6
&&
!
memcmp
(
arg_str
,
"@delme"
,
6
))
{
RedisModule_CommandFilterArgDelete
(
filter
,
pos
);
continue
;
}
if
(
arg_len
==
10
&&
!
memcmp
(
arg_str
,
"@replaceme"
,
10
))
{
RedisModule_CommandFilterArgReplace
(
filter
,
pos
,
RedisModule_CreateString
(
NULL
,
"--replaced--"
,
12
));
}
else
if
(
arg_len
==
13
&&
!
memcmp
(
arg_str
,
"@insertbefore"
,
13
))
{
RedisModule_CommandFilterArgInsert
(
filter
,
pos
,
RedisModule_CreateString
(
NULL
,
"--inserted-before--"
,
19
));
pos
++
;
}
else
if
(
arg_len
==
12
&&
!
memcmp
(
arg_str
,
"@insertafter"
,
12
))
{
RedisModule_CommandFilterArgInsert
(
filter
,
pos
+
1
,
RedisModule_CreateString
(
NULL
,
"--inserted-after--"
,
18
));
pos
++
;
}
else
if
(
arg_len
==
4
&&
!
memcmp
(
arg_str
,
"@log"
,
4
))
{
log
=
1
;
}
pos
++
;
}
}
cmd
->
argv
[
0
]
=
RedisModule_CreateString
(
ctx
,
log_command_name
,
sizeof
(
log_command_name
)
-
1
);
cmd
->
argc
++
;
if
(
log
)
RedisModule_CommandFilterArgInsert
(
filter
,
0
,
RedisModule_CreateString
(
NULL
,
log_command_name
,
sizeof
(
log_command_name
)
-
1
));
}
}
int
RedisModule_OnLoad
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
int
RedisModule_OnLoad
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
...
...
src/redismodule.h
View file @
dc5edc7b
...
@@ -150,6 +150,7 @@ typedef struct RedisModuleBlockedClient RedisModuleBlockedClient;
...
@@ -150,6 +150,7 @@ typedef struct RedisModuleBlockedClient RedisModuleBlockedClient;
typedef
struct
RedisModuleClusterInfo
RedisModuleClusterInfo
;
typedef
struct
RedisModuleClusterInfo
RedisModuleClusterInfo
;
typedef
struct
RedisModuleDict
RedisModuleDict
;
typedef
struct
RedisModuleDict
RedisModuleDict
;
typedef
struct
RedisModuleDictIter
RedisModuleDictIter
;
typedef
struct
RedisModuleDictIter
RedisModuleDictIter
;
typedef
struct
RedisModuleCommandFilterCtx
RedisModuleCommandFilterCtx
;
typedef
int
(
*
RedisModuleCmdFunc
)(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
);
typedef
int
(
*
RedisModuleCmdFunc
)(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
);
typedef
void
(
*
RedisModuleDisconnectFunc
)(
RedisModuleCtx
*
ctx
,
RedisModuleBlockedClient
*
bc
);
typedef
void
(
*
RedisModuleDisconnectFunc
)(
RedisModuleCtx
*
ctx
,
RedisModuleBlockedClient
*
bc
);
...
@@ -162,12 +163,7 @@ typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value
...
@@ -162,12 +163,7 @@ typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value
typedef
void
(
*
RedisModuleTypeFreeFunc
)(
void
*
value
);
typedef
void
(
*
RedisModuleTypeFreeFunc
)(
void
*
value
);
typedef
void
(
*
RedisModuleClusterMessageReceiver
)(
RedisModuleCtx
*
ctx
,
const
char
*
sender_id
,
uint8_t
type
,
const
unsigned
char
*
payload
,
uint32_t
len
);
typedef
void
(
*
RedisModuleClusterMessageReceiver
)(
RedisModuleCtx
*
ctx
,
const
char
*
sender_id
,
uint8_t
type
,
const
unsigned
char
*
payload
,
uint32_t
len
);
typedef
void
(
*
RedisModuleTimerProc
)(
RedisModuleCtx
*
ctx
,
void
*
data
);
typedef
void
(
*
RedisModuleTimerProc
)(
RedisModuleCtx
*
ctx
,
void
*
data
);
typedef
void
(
*
RedisModuleCommandFilterFunc
)
(
RedisModuleCtx
*
ctx
,
RedisModuleCommandFilterCtx
*
filter
);
typedef
struct
RedisModuleFilteredCommand
{
RedisModuleString
**
argv
;
int
argc
;
}
RedisModuleFilteredCommand
;
typedef
void
(
*
RedisModuleCommandFilterFunc
)
(
RedisModuleCtx
*
ctx
,
RedisModuleFilteredCommand
*
cmd
);
#define REDISMODULE_TYPE_METHOD_VERSION 1
#define REDISMODULE_TYPE_METHOD_VERSION 1
typedef
struct
RedisModuleTypeMethods
{
typedef
struct
RedisModuleTypeMethods
{
...
@@ -345,6 +341,11 @@ void REDISMODULE_API_FUNC(RedisModule_SetClusterFlags)(RedisModuleCtx *ctx, uint
...
@@ -345,6 +341,11 @@ void REDISMODULE_API_FUNC(RedisModule_SetClusterFlags)(RedisModuleCtx *ctx, uint
int
REDISMODULE_API_FUNC
(
RedisModule_ExportSharedAPI
)(
RedisModuleCtx
*
ctx
,
const
char
*
apiname
,
void
*
func
);
int
REDISMODULE_API_FUNC
(
RedisModule_ExportSharedAPI
)(
RedisModuleCtx
*
ctx
,
const
char
*
apiname
,
void
*
func
);
void
*
REDISMODULE_API_FUNC
(
RedisModule_GetSharedAPI
)(
RedisModuleCtx
*
ctx
,
const
char
*
apiname
);
void
*
REDISMODULE_API_FUNC
(
RedisModule_GetSharedAPI
)(
RedisModuleCtx
*
ctx
,
const
char
*
apiname
);
int
REDISMODULE_API_FUNC
(
RedisModule_RegisterCommandFilter
)(
RedisModuleCtx
*
ctx
,
RedisModuleCommandFilterFunc
cb
);
int
REDISMODULE_API_FUNC
(
RedisModule_RegisterCommandFilter
)(
RedisModuleCtx
*
ctx
,
RedisModuleCommandFilterFunc
cb
);
int
REDISMODULE_API_FUNC
(
RedisModule_CommandFilterArgsCount
)(
RedisModuleCommandFilterCtx
*
filter
);
const
RedisModuleString
*
REDISMODULE_API_FUNC
(
RedisModule_CommandFilterArgGet
)(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
);
int
REDISMODULE_API_FUNC
(
RedisModule_CommandFilterArgInsert
)(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
,
RedisModuleString
*
arg
);
int
REDISMODULE_API_FUNC
(
RedisModule_CommandFilterArgReplace
)(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
,
RedisModuleString
*
arg
);
int
REDISMODULE_API_FUNC
(
RedisModule_CommandFilterArgDelete
)(
RedisModuleCommandFilterCtx
*
filter
,
int
pos
);
#endif
#endif
/* This is included inline inside each Redis module. */
/* This is included inline inside each Redis module. */
...
@@ -509,6 +510,11 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
...
@@ -509,6 +510,11 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API
(
ExportSharedAPI
);
REDISMODULE_GET_API
(
ExportSharedAPI
);
REDISMODULE_GET_API
(
GetSharedAPI
);
REDISMODULE_GET_API
(
GetSharedAPI
);
REDISMODULE_GET_API
(
RegisterCommandFilter
);
REDISMODULE_GET_API
(
RegisterCommandFilter
);
REDISMODULE_GET_API
(
CommandFilterArgsCount
);
REDISMODULE_GET_API
(
CommandFilterArgGet
);
REDISMODULE_GET_API
(
CommandFilterArgInsert
);
REDISMODULE_GET_API
(
CommandFilterArgReplace
);
REDISMODULE_GET_API
(
CommandFilterArgDelete
);
#endif
#endif
if
(
RedisModule_IsModuleNameBusy
&&
RedisModule_IsModuleNameBusy
(
name
))
return
REDISMODULE_ERR
;
if
(
RedisModule_IsModuleNameBusy
&&
RedisModule_IsModuleNameBusy
(
name
))
return
REDISMODULE_ERR
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment